mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-17 07:40:22 +00:00
docs(dependency injecton): rewrite
This commit is contained in:
parent
581f93ae56
commit
2e90cdc3d4
12 changed files with 244 additions and 290 deletions
|
|
@ -1,32 +0,0 @@
|
|||
@ngdoc overview
|
||||
@name Developer Guide: About Dependency Injection (DI)
|
||||
@description
|
||||
|
||||
Dependency Injection (DI) is an object-oriented software design pattern that supports the
|
||||
decoupling and dependency management of application components.
|
||||
|
||||
The idea behind DI is to decouple each component from all of the other components that it depends
|
||||
on to do its particular job. The way this is done in DI is by moving the responsibility for
|
||||
managing dependencies out of each individual component and into a provider component. The provider
|
||||
(or injector) component manages the life cycles and dependencies for all of the other components in
|
||||
an application.
|
||||
|
||||
Angular has a built-in dependency management subsystem that helps to make your applications easier
|
||||
to develop, understand, and test.
|
||||
|
||||
For more information on DI in general, see {@link http://en.wikipedia.org/wiki/Dependency_injection
|
||||
Dependency Injection} at Wikipedia, and {@link http://martinfowler.com/articles/injection.html
|
||||
Inversion of Control} by Martin Fowler, or read about DI in your favorite software design pattern
|
||||
book.
|
||||
|
||||
|
||||
## Related Topics
|
||||
|
||||
* {@link dev_guide.di.understanding_di Understanding DI in Angular}
|
||||
* {@link dev_guide.services Angular Services}
|
||||
|
||||
|
||||
## Related API
|
||||
|
||||
* {@link api/angular.module.ng Service API}
|
||||
* {@link api/angular.injector Angular Injector API}
|
||||
|
|
@ -1,193 +0,0 @@
|
|||
@ngdoc overview
|
||||
@name Developer Guide: DI: Understanding DI in Angular
|
||||
@description
|
||||
|
||||
|
||||
While DI is widely used in statically typed languages such as Java or C++, it has not been widely
|
||||
used in JavaScript. Angular brings the benefits of DI into JavaScript apps.
|
||||
|
||||
In angular, DI is implemented as a subsystem that manages dependencies between services,
|
||||
controllers, widgets, and filters.
|
||||
|
||||
Services are objects that handle common tasks in web applications. Angular provides several {@link
|
||||
api/angular.module.ng built-in services}, and you can create your
|
||||
{@link dev_guide.services.creating_services own custom services}.
|
||||
|
||||
The main job of angular's DI subsystem is to provide services to angular components that depend on
|
||||
them. The way the DI subsystem provides services is as follows: all services are registered with
|
||||
angular's {@link api/angular.module.ng service API}, and all components that depend on services
|
||||
define those dependencies as a property (`$inject`). With this information, the DI subsystem
|
||||
manages the creation of service objects and the provision of those objects to the components that
|
||||
need them, at the time they need them. The following illustration steps through the sequence of
|
||||
events:
|
||||
|
||||
<img src="img/guide/di_sequence_final.png">
|
||||
|
||||
In the illustration above, the dependency injection sequence proceeds as follows:
|
||||
|
||||
1. Module "phonecat" is created and all the service providers are registered with this module.
|
||||
(the "ng" module is created by Angular behind the scenes as well)
|
||||
2. `ngApp` triggers bootstrap sequence on given element, during which angular creates injector,
|
||||
loads "phonecat" and "ng" modules and compiles the template.
|
||||
3. The `ngController` directive implicitly creates a new child scope and instantiates
|
||||
`PhoneListCtrl` controller.
|
||||
4. Injector identifies the `$http` service as `PhoneListCtrl` controller's only dependency.
|
||||
5. Injector checks its instances cache whether the `$http` service has already been instantiated.
|
||||
If not uses the provider from the available modules to construct it.
|
||||
6. Injector provides the instance of `$http` service to the `PhoneListCtrl` controller constructor.
|
||||
|
||||
|
||||
## How Scope Relates to DI
|
||||
|
||||
The root scope of the application is just a service that is available for injection to any part of
|
||||
the application under the service name "$rootScope".
|
||||
|
||||
|
||||
## Inferring dependencies from the signature of the factory function or constructor
|
||||
|
||||
**EXPERIMENTAL FEATURE**: This is an experimental feature. See the important note at the end of
|
||||
this section for drawbacks.
|
||||
|
||||
We resort to `$inject` and our own annotation because there is no way in JavaScript to get a list
|
||||
of arguments. Or is there? It turns out that calling `.toString()` on a function returns the
|
||||
function declaration along with the argument names as shown below:
|
||||
|
||||
<pre>
|
||||
function myFn(a,b){}
|
||||
expect(myFn.toString()).toEqual('function myFn(a,b){}');
|
||||
</pre>
|
||||
|
||||
This means that angular can infer the function names after all and use that information to generate
|
||||
the `$inject` annotation automatically. Therefore the following two function definitions are
|
||||
equivalent:
|
||||
|
||||
<pre>
|
||||
// given a user defined service
|
||||
angular.module('module1', [], function($provide) {
|
||||
$provide.factory('serviceA', ...);
|
||||
});
|
||||
|
||||
// inject '$window', 'serviceA', curry 'name';
|
||||
function fnA($window, serviceA, name){};
|
||||
fnA.$inject = ['$window', 'serviceA'];
|
||||
|
||||
// inject '$window', 'serviceA', curry 'name';
|
||||
function fnB($window, serviceA_, name){};
|
||||
// implies: fnB.$inject = ['$window', 'serviceA'];
|
||||
</pre>
|
||||
|
||||
If angular does not find a `$inject` annotation on the function, then it calls the `.toString()`
|
||||
method and tries to infer what should be injected by using function argument names as dependency
|
||||
identifiers.
|
||||
|
||||
**IMPORTANT**
|
||||
Minifiers/obfuscators change the names of function arguments and will therefore break the `$inject`
|
||||
inference. For this reason, either explicitly declare the `$inject` or do not use
|
||||
minifiers/obfuscators. In the future, we may provide a pre-processor which will scan the source
|
||||
code and insert the `$inject` into the source code so that it can be minified/obfuscated.
|
||||
|
||||
|
||||
### Dependency inference and variable name shadowing
|
||||
|
||||
During inference, the injector considers argument names with leading and trailing underscores to be
|
||||
equivivalent to the name without these underscores. For example `_fooSvc_` argument name is treated
|
||||
as if it was `fooSvc`, this is useful especially in tests where variable name shadowing can cause
|
||||
some friction. This is best illustrated on examples:
|
||||
|
||||
When testing a service, it's common to need a reference to it in every single test. This can be
|
||||
done in jasmine with DI inference like this:
|
||||
|
||||
<pre>
|
||||
describe('fooSvc', function() {
|
||||
it('should do this thing', inject(function(fooSvc) {
|
||||
//test fooSvc
|
||||
}));
|
||||
|
||||
it('should do that thing', inject(function(fooSvc) {
|
||||
//test fooSvc
|
||||
}));
|
||||
|
||||
// more its
|
||||
});
|
||||
</pre>
|
||||
|
||||
... but having to inject the service over and over gets easily tiresome.
|
||||
|
||||
It's likely better to rewrite these tests with a use of jasmine's `beforeEach`:
|
||||
|
||||
<pre>
|
||||
describe('fooSvc', function() {
|
||||
var fooSvc;
|
||||
|
||||
beforeEach(inject(function(fooSvc) {
|
||||
fooSvc = fooSvc; // DOESN'T WORK! outer fooSvc is being shadowed
|
||||
}));
|
||||
|
||||
it('should do this thing', function() {
|
||||
//test fooSvc
|
||||
});
|
||||
|
||||
it('should do that thing', function() {
|
||||
//test fooSvc
|
||||
});
|
||||
|
||||
// more its
|
||||
});
|
||||
</pre>
|
||||
|
||||
This obviously won't work because `fooSvc` variable in the describe block is being shadowed by the
|
||||
`fooSvc` argument of the beforeEach function. So we have to resort to alternative solutions, like
|
||||
for example use of array notation to annotate the beforeEach fn:
|
||||
|
||||
<pre>
|
||||
describe('fooSvc', function() {
|
||||
var fooSvc;
|
||||
|
||||
beforeEach(inject(['fooSvc', function(fooSvc_) {
|
||||
fooSvc = fooSvc_;
|
||||
}]));
|
||||
|
||||
it('should do this thing', function() {
|
||||
//test fooSvc
|
||||
});
|
||||
|
||||
it('should do that thing', function() {
|
||||
//test fooSvc
|
||||
});
|
||||
});
|
||||
</pre>
|
||||
|
||||
|
||||
That's better, but it's still annoying, especially if you have many services to inject.
|
||||
|
||||
To resolve this shadowing problem, the injector considers `_fooSvc_` argument names equal to
|
||||
`fooSvc`, so the test can be rewritten like this:
|
||||
|
||||
<pre>
|
||||
describe('fooSvc', function() {
|
||||
var fooSvc;
|
||||
|
||||
beforeEach(inject(function(_fooSvc_) {
|
||||
fooSvc = _fooSvc_;
|
||||
}));
|
||||
|
||||
it('should do this thing', function() {
|
||||
//test fooSvc
|
||||
});
|
||||
|
||||
it('should do that thing', function() {
|
||||
//test fooSvc
|
||||
});
|
||||
|
||||
// more its
|
||||
});
|
||||
</pre>
|
||||
|
||||
|
||||
## Related Topics
|
||||
|
||||
* {@link dev_guide.services Angular Services}
|
||||
|
||||
## Related API
|
||||
|
||||
* {@link api/angular.module.ng Services API}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
@ngdoc overview
|
||||
@name Developer Guide: DI: Using DI in Controllers
|
||||
@description
|
||||
|
||||
The most common place to use dependency injection in angular applications is in {@link
|
||||
dev_guide.mvc.understanding_controller controllers}. Here is a simple example:
|
||||
|
||||
<pre>
|
||||
function MyController($location){
|
||||
// do stuff with the $location service
|
||||
}
|
||||
MyController.$inject = ['$location'];
|
||||
</pre>
|
||||
|
||||
In this example, the `MyController` constructor function takes one argument, the {@link
|
||||
api/angular.module.ng.$location $location} service. Angular is then responsible for supplying the
|
||||
instance of `$location` to the controller when the constructor is instantiated. There are two ways
|
||||
to cause controller instantiation – by configuring routes with the `$location` service, or by
|
||||
referencing the controller from the HTML template, as follows:
|
||||
|
||||
<pre>
|
||||
<!doctype html>
|
||||
<html ng-controller="MyController" ng-app>
|
||||
<script src="http://code.angularjs.org/angular.min.js"></script>
|
||||
<body>
|
||||
...
|
||||
</body>
|
||||
</html>
|
||||
</pre>
|
||||
|
||||
When angular is instantiating your controller, it needs to know what services, if any, should be
|
||||
injected (passed in as arguments) into the controller. Since there is no reflection in JavaScript,
|
||||
we have to supply this information to angular in the form of an additional property on the
|
||||
controller constructor function called `$inject`. Think of it as annotations for JavaScript.
|
||||
|
||||
<pre>
|
||||
MyController.$inject = ['$location'];
|
||||
</pre>
|
||||
|
||||
The information in `$inject` is then used by the {@link api/angular.injector injector} to call the
|
||||
function with the correct arguments.
|
||||
|
||||
|
||||
## Related Topics
|
||||
|
||||
* {@link dev_guide.di About Dependency Injection}
|
||||
* {@link dev_guide.di.understanding_di Understanding Dependency Injection in Angular}
|
||||
* {@link dev_guide.services Angular Services}
|
||||
|
||||
## Related API
|
||||
|
||||
* {@link api/angular.injector Angular Injector API}
|
||||
|
|
@ -12,7 +12,7 @@ The MVC pattern greatly summarized:
|
|||
* Separate applications into distinct presentation, data, and logic components
|
||||
* Encourage loose coupling between these components
|
||||
|
||||
Along with {@link dev_guide.services services} and {@link dev_guide.di dependency injection}, MVC
|
||||
Along with {@link dev_guide.services services} and {@link di dependency injection}, MVC
|
||||
makes angular applications better structured, easier to maintain and more testable.
|
||||
|
||||
The following topics explain how angular incorporates the MVC pattern into the angular way of
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ needed for a single view.
|
|||
|
||||
The most common way to keep controllers slim is by encapsulating work that doesn't belong to
|
||||
controllers into services and then using these services in controllers via dependency injection.
|
||||
This is discussed in the {@link dev_guide.di Dependency Injection} {@link dev_guide.services
|
||||
This is discussed in the {@link di Dependency Injection} {@link dev_guide.services
|
||||
Services} sections of this guide.
|
||||
|
||||
Do not use controllers for:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ to write your own custom services. To do this you begin by registering a service
|
|||
with a module either via the {@link api/angular.module Module#factory api} or directly
|
||||
via the {@link api/angular.module.AUTO.$provide $provide} api inside of module config function.
|
||||
|
||||
All angular services participate in {@link dev_guide.di dependency injection (DI)} by registering
|
||||
All angular services participate in {@link di dependency injection (DI)} by registering
|
||||
themselves with Angular's DI system (injector) under a `name` (id) as well as by declaring
|
||||
dependencies which need to be provided for the factory function of the registered service. The
|
||||
ability to swap dependencies for mocks/stubs/dummies in tests allows for services to be highly
|
||||
|
|
@ -49,7 +49,7 @@ create this instance when called.
|
|||
# Dependencies
|
||||
|
||||
Services can not only be depended upon, but also have its own dependencies. These can be specified
|
||||
as arguments of the factory function. {@link dev_guide.di.understanding_di Read more} about the DI
|
||||
as arguments of the factory function. {@link di.understanding_di Read more} about the DI
|
||||
in Angular and the use of array notation and $inject property to make DI annotation
|
||||
minification-proof.
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
Services are a feature that angular brings to client-side web apps from the server side, where
|
||||
services have been commonly used for a long time. Services in angular apps are substitutable
|
||||
objects that are wired together using {@link dev_guide.di dependency injection (DI)}. Services are
|
||||
most often used with {@link dev_guide.di dependency injection}, also a key feature of angular apps.
|
||||
objects that are wired together using {@link di dependency injection (DI)}. Services are
|
||||
most often used with {@link di dependency injection}, also a key feature of angular apps.
|
||||
|
||||
|
||||
## Related Topics
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ above). You can also create your own custom services.
|
|||
|
||||
## Related Topics
|
||||
|
||||
* {@link dev_guide.di About Angular Dependency Injection}
|
||||
* {@link di About Angular Dependency Injection}
|
||||
* {@link dev_guide.services.creating_services Creating Angular Services}
|
||||
* {@link dev_guide.services.managing_dependencies Managing Service Dependencies}
|
||||
* {@link dev_guide.services.testing_services Testing Angular Services}
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ myClass.doWork();
|
|||
|
||||
Notice that no global variables were harmed in the writing of this test.
|
||||
|
||||
Angular comes with {@link dev_guide.di dependency-injection} built in which makes the right thing
|
||||
Angular comes with {@link di dependency-injection} built in which makes the right thing
|
||||
easy to do, but you still need to do it if you wish to take advantage of the testability story.
|
||||
|
||||
## Controllers
|
||||
|
|
|
|||
234
docs/content/guide/di.ngdoc
Normal file
234
docs/content/guide/di.ngdoc
Normal file
|
|
@ -0,0 +1,234 @@
|
|||
@ngdoc overview
|
||||
@name Developer Guide: Dependency Injection
|
||||
@description
|
||||
|
||||
# Dependency Injection
|
||||
|
||||
Dependency Injection (DI) is a software design pattern that deals with how code gets hold of its
|
||||
dependencies.
|
||||
|
||||
For in-depth discussion about DI, see {@link http://en.wikipedia.org/wiki/Dependency_injection
|
||||
Dependency Injection} at Wikipedia, {@link http://martinfowler.com/articles/injection.html
|
||||
Inversion of Control} by Martin Fowler, or read about DI in your favorite software design pattern
|
||||
book.
|
||||
|
||||
## DI in a nutshell
|
||||
|
||||
There are only three ways how an object or a function can get a hold of its dependencies:
|
||||
|
||||
1. The dependency can be created, typically using the `new` operator.
|
||||
|
||||
2. The dependency can be looked up by referring to a global variable.
|
||||
|
||||
3. The dependency can be passed in to where it is needed.
|
||||
|
||||
|
||||
The first two option of creating or looking up dependencies are not optimal, because they hard
|
||||
code the dependency, making it difficult, if not impossible, to modify the dependencies.
|
||||
This is especially problematic in tests, where it is often desirable to provide mock dependencies
|
||||
for test isolation.
|
||||
|
||||
The third option is the most viable, since it removes the responsibility of locating the
|
||||
dependency from the component. The dependency is simply handed to the component.
|
||||
|
||||
<pre>
|
||||
function SomeClass(greeter) {
|
||||
this.greeter = greeter
|
||||
}
|
||||
|
||||
SomeClass.prototype.doSomething = function(name) {
|
||||
this.greeter.greet(name);
|
||||
}
|
||||
</pre>
|
||||
|
||||
In the above example the `SomeClass` is not concerned with locating the `greeter` dependency, it
|
||||
is simply handed the `greeter` at runtime.
|
||||
|
||||
This is desirable, but it puts the responsibility of getting hold of the dependency onto the
|
||||
code responsible for the construction of `SomeClass`.
|
||||
|
||||
To manage the responsibility of dependency creation, each angular application has an {@link
|
||||
api/angular.injector injector}. The injector is a service locator that is responsible for
|
||||
construction and lookup of dependencies.
|
||||
|
||||
|
||||
Here is an example of using the injector service.
|
||||
<pre>
|
||||
// Provide the wiring information in a module
|
||||
angular.module('myModule', []).
|
||||
|
||||
// Teach the injector how to build a 'greeter'
|
||||
// Notice that greeter itself is dependent on '$window'
|
||||
factory('greeter', function($window) {
|
||||
// This is a factory function, and is responsible for
|
||||
// creating the 'greet' service.
|
||||
return {
|
||||
greet: function(text) {
|
||||
$window.alert(text);
|
||||
}
|
||||
};
|
||||
}).
|
||||
|
||||
// New injector is created from the module.
|
||||
// (This is usually done automatically by angular bootstrap)
|
||||
var injector = angular.injector('myModule');
|
||||
|
||||
// Request any dependency from the injector
|
||||
var greeter = injector.get('greeter');
|
||||
</pre>
|
||||
|
||||
Asking for dependencies solves the issue of hard coding, but it also means that the injector needs
|
||||
to be passed throughout the application. Passing the injector breaks the {@link
|
||||
http://en.wikipedia.org/wiki/Law_of_Demeter Law of Demeter}. To remedy this, we turn the
|
||||
dependency lookup responsibility to the injector by declaring the dependencies as in this example:
|
||||
|
||||
<pre>
|
||||
<!-- Given this HTML -->
|
||||
<div ng-controller="MyController">
|
||||
<button ng-click="sayHello()">Hello</button>
|
||||
</div>
|
||||
</pre>
|
||||
<pre>
|
||||
// And this controller definition
|
||||
function MyController($scope, greeter) {
|
||||
$scope.sayHello = function() {
|
||||
greeter('Hello World');
|
||||
};
|
||||
}
|
||||
|
||||
// The 'ng-controller' directive does this behind the scenes
|
||||
injector.instantiate(MyController);
|
||||
</pre>
|
||||
|
||||
Notice that by having the `ng-controller` instantiate the class, it can satisfy all of the
|
||||
dependencies of the `MyController` without the controller ever knowing about the injector. This is
|
||||
the best outcome. The application code simply ask for the dependencies it needs, without having to
|
||||
deal with the injector. This setup does not break the Law of Demeter.
|
||||
|
||||
# Dependency Annotation
|
||||
|
||||
How does the injector know what service needs to be injected?
|
||||
|
||||
The application developer needs to provide annotation information, that the injector uses in order
|
||||
to resolve the dependencies. Throughout Angular certain API functions are invoked using the
|
||||
injector, as per the API documentation. The injector needs to know what services to inject into
|
||||
the function. Below are three equivalent ways of annotating your code with service name
|
||||
information. These can be used interchangeably as you see fit and are equivalent.
|
||||
|
||||
# Inferring Dependencies
|
||||
|
||||
The simplest way to get hold of the dependencies, is to assume that the function parameter names
|
||||
are the names of the dependencies.
|
||||
|
||||
<pre>
|
||||
function MyController($scope, greeter) {
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
|
||||
Given a function the injector can infer the names of the service to inject by examining the
|
||||
function declaration and extracting the parameter names. In the above example `$scope`, and
|
||||
`greeter` are two services which need to be injected into the function.
|
||||
|
||||
While straightforward, this method will not work with JavaScript minifiers/obfuscators as they
|
||||
rename the method parameter names. This makes this way of annotating only useful for {@link
|
||||
http://www.pretotyping.org/ pretotyping}, and demo applications.
|
||||
|
||||
# `$inject` Annotation
|
||||
|
||||
To allow the minifers to rename the function parameters and still be able to inject right services
|
||||
the function needs to be annotate with the `$inject` property. The `$inject` property is an array
|
||||
of service names to inject.
|
||||
|
||||
<pre>
|
||||
var MyController = function(renamed$scope, renamedGreeter) {
|
||||
...
|
||||
}
|
||||
MyController.$inject = ['$scope', 'greeter'];
|
||||
</pre>
|
||||
|
||||
Care must be taken that the `$inject` annotation is kept in sync with the actual arguments in the
|
||||
function declaration.
|
||||
|
||||
This method of annotation is useful for controller declarations since it assigns the annotation
|
||||
information with the function.
|
||||
|
||||
# Inline Annotation
|
||||
|
||||
Sometimes using the `$inject` annotation style is not convenient such as when annotating
|
||||
directives.
|
||||
|
||||
For example:
|
||||
<pre>
|
||||
someModule.factory('greeter', function($window) {
|
||||
...;
|
||||
});
|
||||
</pre>
|
||||
|
||||
Results in code bloat do to the need of temporary variable:
|
||||
<pre>
|
||||
var greeterFactory = function(renamed$window) {
|
||||
...;
|
||||
};
|
||||
|
||||
greeterFactory.$inject = ['$window'];
|
||||
|
||||
someModule.factory('greeter', greeterFactory);
|
||||
</pre>
|
||||
|
||||
For this reason the third annotation style is provided as well.
|
||||
<pre>
|
||||
someModule.factory('greeter', ['$window', function(renamed$window) {
|
||||
...;
|
||||
}]);
|
||||
</pre>
|
||||
|
||||
Keep in mind that all of the annotation styles are equivalent and can be used anywhere in Angular
|
||||
where injection is supported.
|
||||
|
||||
|
||||
# Where can I use DI?
|
||||
|
||||
DI is pervasive throughout Angular. It is typically used in controllers and factory methods.
|
||||
|
||||
## DI in controllers
|
||||
|
||||
Controllers are classes which are responsible for application behavior. Recommended way of
|
||||
declaring controllers is:
|
||||
|
||||
<pre>
|
||||
var MyController = function(dep1, dep2) {
|
||||
...
|
||||
}
|
||||
MyController.$inject = ['dep1', 'dep2'];
|
||||
|
||||
MyController.prototype.aMethod = function() {
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
||||
## Factory methods
|
||||
|
||||
Factory methods are responsible for creating most objects in Angular. Examples are directives,
|
||||
services, and filters. The factory methods are register with the module, and the recommended way
|
||||
of declaring factories is:
|
||||
|
||||
<pre>
|
||||
angualar.module('myModule', []).
|
||||
config(['depProvider', function(depProvider){
|
||||
...
|
||||
}]).
|
||||
factory('serviceId', ['depService', function(depService) {
|
||||
...
|
||||
}]).
|
||||
directive('directiveName', ['depService', function(depService) {
|
||||
...
|
||||
}]).
|
||||
filter('filterName', ['depService', function(depService) {
|
||||
...
|
||||
}]).
|
||||
run(['depService', function(depService) {
|
||||
...
|
||||
}]);
|
||||
</pre>
|
||||
|
|
@ -44,7 +44,4 @@ of the following documents before returning here to the Developer Guide:
|
|||
* {@link dev_guide.services.managing_dependencies Managing Service Dependencies}
|
||||
* {@link dev_guide.services.testing_services Testing Angular Services}
|
||||
|
||||
## {@link dev_guide.di About Dependency Injection}
|
||||
|
||||
* {@link dev_guide.di.understanding_di Understanding DI in Angular}
|
||||
* {@link dev_guide.di.using_di_controllers Using DI in Controllers}
|
||||
## {@link di About Dependency Injection}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
* @description
|
||||
* Creates an injector function that can be used for retrieving services as well as for
|
||||
* dependency injection (see {@link guide/dev_guide.di dependency injection}).
|
||||
* dependency injection (see {@link guide/di dependency injection}).
|
||||
*
|
||||
|
||||
* @param {Array.<string|Function>} modules A list of module functions or their aliases. See
|
||||
|
|
|
|||
Loading…
Reference in a new issue