Dependency Injection

16

Considering the injection of dependencies in AngularJS, there are a few ways to do it. The modes as far as I know are:

Form 1:

angular
  .module('meuModulo', [])
  .controller('MeuController', function(dependencia)) {
    //...
  });

Form 2:

angular
  .module('meuModulo', [])
  .controller('MeuController', ['dependencia', function(dependencia)) {
    //...
  }]);

Form 3:

angular
  .module('meuModulo', [])
  .controller('MeuController', MeuController);

MeuController.$inject = ['dependencia'];

function MeuController(dependencia)) {
    //...
}

I used as an example controller but you can use it for factory , directive , filter , etc.

My questions about this are: What are the real differences between ways to inject dependencies? What is the indication for each case? Do you have other ways to do them?

    
asked by anonymous 17.02.2017 / 13:26

3 answers

12

Form 2 and 3 consider the position of the argument, not the name.

In Javascript minification, for example, since variable names change, it could cause errors in your application in Angular.

AngularJs reads the value of the parameter and injects the dependency magically. Since minification would cause $scope to become a , it could cause an error saying that a was not injected.

That is, using $inject or Array with argument names has this goal: You are talking to Angular inject by the position of the parameter, not the name.

So, it would be possible to do something like:

angular.module('app').controller(['$scope', '$http', (a, b) {
    console.log(a); // Retorna a instância de '$scope'
}]);
    
17.02.2017 / 13:31
9

Only one answer as an alternative, providing a 4th method (which is what I use), so you have more alternatives.

Wallace's answer is perfect, you should keep in mind that if you run code mining, it is important that you keep the injection order and dependencies the same. Doing this manually can be cumbersome and increase chances of error.

It is always recommended to use form 2 or 3. The difference between them is just a matter of code preference. Some prefer one while others prefer one.

If you use grunt , you can use this plugin that will make your life a lot easier.

This would then be the 4th method, as you do not have to worry about adding the injection, it does it automatically. Based on your example, you could write your code like this:

/* @ngInject */
.controller('MeuController', function(dependencia) {
    //...
});

And it would be compiled to:

.controller('MeuController', function(dependencia) {
    //...
});
MeuController.$inject = ['dependencia'];

This way you do not worry about their order. If your project has 10 injections and you need to remove one that is in the middle, you would not have to manually change the order.

    
17.02.2017 / 14:55
6

Form 1 ( Implicit Annotation ):

This is the simplest way to handle dependencies, and assumes that the signatures of function parameters are dependency names. In the above example dependencia is a service that needs to be injected into the function. One of the advantages of this method is that there is no array of names to keep the parameters of the function synchronized. You can rearrange dependencies freely. However this method will not work with minifiers / obfuscated because the parameters are renamed. Because of these caveats it is recommended to avoid this.

Form 2 ( Inline Array Annotation ):

This is the recommended method according to the AngularJS documentation . So we pass an array consisting of a list of strings (the names of dependencies) followed by the function itself. When this type of annotation is used, care must be taken to keep the parameters and function declaration synchronized.

Form 3 ( $inject Property Annotation ):

This is the method indicated by Angular Styleguide of John Papa (One of those responsible for the development of AngularJS). In this way the minifiers will still be able to be used and correctly inject the services. The function must have the $inject property annotation which is an array of the names of the injected services. In this scenario the order of the injected values must be equal to the order of the parameters in the function.

References:

22.02.2017 / 15:46