Dependency Injection is a software design pattern used to handle code dependencies.
In general, there are three ways to get a function to rely on it:
Its dependencies can be created, usually with the new operator.
Ability to find dependencies through global variables.
Dependencies can be imported when they are needed.
The first two are not very good, because they require hard coding of dependencies, making it difficult to modify dependencies. This is especially difficult when testing, because testing a part in isolation often requires simulating its dependencies.
The third approach is best, because it does not have to actively seek and acquire dependencies in the component, but instead relies on the outside world to pass in.
As an example:
function SomeClass (greeter) { this.greeter =function(name) { this . Greeter.greet (name);}
In the above example SomeClass does not care where to get the dependency called greeter. This is the result we want, but it also gives the task of getting dependencies to the code responsible for creating the SomeClass.
Each ANGULARJS application has an injector (injector) to handle the creation of dependencies. An injector is a service locator that is responsible for locating and creating dependencies. As an example:
Angular.module (' MyModule ', []). //tell the injector how to create this greeter //Note that the greeter itself relies on ' $window 'Factory (' Greeter ',function($window) {//This method, which we call the factory method, is used to create this greeter service return{greet:function(text) {$window. alert (text); } }; })//in module MyModule, create a new injector//(This is often done automatically at angular startup)varInjector = Angular.injector (' MyModule '));//get greeter This service from this injectorvarGreeter = Injector.get (' greeter ');
The problem of hard coding is solved by request dependency, but it also means that the injector needs to be passed in the application, which violates the Dimitri rule. We solve the dependency lookup by using the method declared in the following example.
This HTML--><div ng-controller= "Mycontroller" > <button ng-click= "SayHello ()" >Hello</button> </div>// and this controller definitionfunction mycontroller ($scope, greeter) { function () { greeter (' Hello World ');} ;} // The ' ng-controller ' directive did the following things Injector.instantiate (Mycontroller);
Note that by using the ng-controller
controller class to instantiate, yes, the controller and the injector are no longer associated, which is the best result. The code in the controller can simply request dependencies without having to process the injector. This approach does not destroy the Dimitri law.
How does the injector know what dependencies need to be injected?
The injector requires the application to provide some markup to represent the dependencies it needs. In some API documents about ANGULARJS you will see that the function is called by the injector. The injector needs to know what the function needs to depend on. Here are three equivalent methods that represent the dependencies that you need. These methods can be replaced with each other and are equivalent.
(1) The simplest way to handle dependencies is to assume that a function's parameter name is a dependent name
function Mycontroller ($scope, greeter) { ...}
Given an injector, you can get the function name by checking the function declaration to know which function to rely on. In the above example, $scope
and greeter
is the dependency that needs to be injected into the function.
Frankly speaking, using this method can not be used JavaScript minifiers/obfuscators
(some to shorten the JS class library), because they will change the variable name.
(2) To allow the Compression class library to rename the parameters of the function, while the injector can correctly handle dependencies, the function needs to use the $inject property. This property is an array that contains the names of the dependencies.
var function (Renamed$scope, renamedgreeter) { = [' $scope ', ' greeter '];
Note that the values in the $inject tag correspond to the parameters of the function declaration.
This approach is appropriate for the Controller declaration because the Controller has an explicit declaration token.
(3) Sometimes it is not convenient to use $inject markers, such as when declaring instructions.
Using $inject can cause code bloat:
var function (Renamed$window) { = [' $window '];somemodule.factory (' greeter ', greeterfactory);
In this case, we recommend using the third method:
function (Renamed$window) { ...;}]);
Dependency injection is common in angularjs and is commonly used in controller and factory methods.
Dependency Injection in the controller:
A controller is a class that is responsible for applying behavior. The recommended controller declaration methods are as follows:
var function (DEP1, DEP2) { = [' Dep1 ', ' Dep2 'function() { ...}
Dependency Injection of factory methods:
The factory method is responsible for creating most of the objects in the Angularjs. such as directives, services, filters. Factory methods are generally used in modules, and the recommended methods are as follows:
Angular.module (' MyModule ', []). Config ([function(depprovider) { ... }]). Factory (function(depservice) { ... }]). Directive (function(depservice) { ... }]). Filter (function(depservice) { ... }]). Run ([function(depservice) {... }]);
Come on!
Angularjs Development Guide 10:angularjs Dependency Injection