Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does implicit/inline/$inject dependency injection work in AngularJS?

I'm new to AngularJS and I would like to understand more about the dependencies that are being injected by default. While reading through code I've noticed that sometimes dependencies are explicitly declared beforehand, and sometimes they aren't. For example:

someModule.controller('MyController', ['$scope', 'someService', function($scope, someService) {
  // ...
}]);

Gives the same results as:

someModule.controller('MyController', function($scope, someService) {
  // ...
});

How does this work? Is Angular assuming that the modules being injected are named the same as the variables in the parameters?

Also, strangely enough, if you do specify the dependencies that are going to be injected, you must specify all of them and in the right order, otherwise nothing will work. For example, this is broken code:

someModule.controller('MyController', ['someService', '$scope', function($scope, someService) {
  // Won't give us any errors, but also won't load the dependencies properly
}]);

Can someone clarify to me how is this whole process working? Thank you very much!!

like image 952
David Meza Avatar asked Sep 24 '15 04:09

David Meza


People also ask

How does Dependency Injection work in AngularJS?

Dependency Injection (DI) is a software design pattern that deals with how components get hold of their dependencies. The AngularJS injector subsystem is in charge of creating components, resolving their dependencies, and providing them to other components as requested.

What is Dependency Injection explain how Dependency Injection works in Angular?

Dependency injection, or DI, is one of the fundamental concepts in Angular. DI is wired into the Angular framework and allows classes with Angular decorators, such as Components, Directives, Pipes, and Injectables, to configure dependencies that they need.

Which components can be injected as dependency in AngularJS?

26) Which of the following components can be injected as a dependency in AngularJS? Answer: D is the correct answer. The "Application Module" can be injected as a dependency in AngularJS.

How does Dependency Injection work internally?

DI is a process whereby objects define their dependencies. The other objects they work with—only through constructor arguments or arguments to a factory method or property—are set on the object instance after it is constructed or returned from a factory method.


1 Answers

Yes, dependency injection in Angular works via the names of the components you (and Angular - for the internal ones) registered.

Below is an example showing how a service is registered and injected into a controller using several different annotations. Please note that dependency injection always works the same in Angular, i.e. it doesn't matter if you are injecting something into a controller, a directive or a service.

app.service('myService', function () {
    // registering a component - in this case a service
    // the name is 'myService' and is used to inject this
    // service into other components
});

Two use (inject) this component in other components, there are three different annotations I am aware of:

1. Implicit Annotation

You can either specify a constructor function which takes as parameters all the dependencies. And yes, the names need to be the same as when these components were registered:

app.controller('MyController', function ($http, myService) {
    // ..
});

2. Inline Array Annotation

Or you can use a notation using an array, where the last parameter is the constructor function with all the injectables (variable names do not matter in this case). The other values in the array need to be strings that match the names of the injectables. Angular can this way detect the order of the injectables and do so appropriately.

app.controller('MyController', ['$http', 'myService', function ($h, m) {
    /* Now here you can use all properties of $http by name of $h & myService by m */
    // Example
    $h.x="Putting some value"; // $h will be $http for angular app
}]);

3. $inject Property Annotation

A third option is to specify the $inject-property on the constructor function:

function MyController($http, myService) {
    // ..
}
MyController.$inject = ['$http', 'myService'];
app.controller('MyController', MyController);

The reason why the last two options are available, at least as far as I know, is due to issues which occured when minifying the JavaScript files which led to the names of the parameters being renamed. Angular then wasn't able to detect what to inject anymore. In the second two cases the injectables are defined as strings, which are not touched during minification.

I would recommend to use version 2 or 3, as version 1 won't work with minification/obfuscation. I prefer version 3 as from my point of view it is the most explicit.

You can find some more detailed information in the internet, e.g. on the Angular Developer Guide.

like image 72
PzYon Avatar answered Nov 15 '22 08:11

PzYon