What are the differences between the forms of dependency injection?

Asked

Viewed 1,408 times

16

Considering the injection of dependencies into Angularjs, there are some 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 the controller but can use to factory, directive, filter, etc..

My questions about this are: What are the real differences between the ways to inject dependencies? What is the indication for each case? There are other ways to accomplish them?

  • 2

    I always use the forma 2 +1 for the question ...

  • Your 3rd option seems more suitable with the standards of good practice. I recommend giving a read on the guide of John Pope, helped me a lot! https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md I hope I helped. Hug

3 answers

12


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

In Javascript minification, for example, once variable names are changed, it could cause errors in your Angular application.

Angularjs reads the value of the parameter and injects the dependency magically. How the minification would do $scope transform into a, could cause a mistake by saying that a was not injected.

That is, the use of $inject or of Array with the names of the arguments have this goal: You are talking to Angular to inject by the position of the parameter, and not by 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`
}]);
  • It is true, even in the Angular forum recommends not to use the form 1. Using ASP.Net and making the Bundle of the Javascript files, using the first form can generate reference error.

9

Just an alternative answer, 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’re going to run code minification, it’s important that you keep the injection order and dependencies the same. Doing this manually can be laborious and increase chances of error.

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


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

This would then be the 4th method, because you don’t 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 for:

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

This way you don’t care about their order. If your project has 10 injections and you need to remove one that’s in the middle, you don’t need to manually change the order.

6

Form 1 (Implicit Annotation):

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

Form 2 (Inline Array Annotation) :

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

Form 3 ($inject Property Annotation):

It is the method indicated by Angular Styleguide of John Papa (One of those responsible for the development of Angularjs). In this way, mini-generators will still be able to be used and inject the services correctly. The function needs to be annotated $inject 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:

Browser other questions tagged

You are not signed in. Login or sign up in order to post.