Skip to content

Dependency Injection in AngularJS

In this article, we will understand what is Dependency Injection and how it is used in AngularJS. We have demonstrated the Dependency Injection in AngularJS using simple examples. Go through the following links to learn what is AngularJS and what are the basic building blocks of AngularJS.

What is Dependency Injection (DI)?

Dependency Injection is a software design pattern or a technique where one object supplies the dependencies of another object. As the name suggests, a dependency (service) is an object to be used/invoked and injection is a way of passing a dependency to a dependent object(client) where that would use it.

The main intention of DI is to prohibit dependency object creation (by new or static methods) in each dependent object. The dependent object has to accept the values passed from the outside. Its fundamental requirement is to decouple the objects to an extent that even if there is a change in dependency object should not affect the dependent object.

Dependency Injection requires a separate code (called an injector) which takes the responsibility of creating a client and its dependencies to it.

With the above statements, we can conclude that Dependency Injection involves the below-mentioned roles.

  • A dependency object (service)
  • A dependent Object (client)
  • An interface – defines as how a client uses the service
  • An injector – responsible for constructing the services and injecting them into the client.

In AngularJS, the angular injector is responsible for creating the object and passing its required dependencies.

Dependency Injection in AngularJS

How to use Dependency Injection in AngularJS?

In AngularJS, we will see a simple example to understand how DI is used.

var app = angular.module('myApp', []);
app.controller('myCtrl', ["$scope","serviceA","serviceB",
function($scope, serviceA, serviceB) {
  $scope.method = function(){
  };
}]);

As we can see in the above example, we have a module called “myApp” and added a controller called “myCtrl” to the module. Here we have something called $scope, serviceA, and serviceB, these are nothing but the dependencies on which a controller is dependent. This is how DI is used to pass the dependencies without creating an object in the controller.

Dependency Annotation:

In AngularJS, the functions such as service factories, and controllers should be annotated so that the injector should know what services to inject into the function. It is just a simple way to make sure that the right service is invoked.

There are 3 ways to annotate your functions and they are:

  • Using inline array annotation
  • Using $inject property annotation
  • Using implicit annotation

Inline Array Annotation:

This is the most preferred way to annotate your application components. Here we use an array to pass the parameters. You can see the example below.

var app = angular.module('myApp', []);
app.controller('myCtrl', ["$scope","serviceA","serviceB",
function($scope, serviceA, serviceB) {
  //to do......
}]);

As we can see, an array consists of a list of dependencies followed by a function is used.

When using this type of annotation, you need to keep in mind that the annotation array should be in sync with the parameters passed to the function.

$inject Property Annotation:

This type of annotation allows you to rename the function parameters and still the correct service is invoked. This is done using $inject property. The function needs to be annotated with this property. The $inject property is an array of service names to inject.

You can see the below example.

var app = angular.module('myApp', []);

app.controller('myCtrl', myCtrl);
myCtrl.$inject = ["$scope","serviceA","serviceB"];

function myCtrl($scope, serviceA, serviceB) {

}]);

In this type also, the ordering of the values in the $inject array must match the ordering of the parameters in myCtrl. It is similar to array annotation except that an array is separated by $inject property.

Implicit Annotation:

The easiest way of annotating your function is just to assume that the function parameters itself are the name of dependencies.

var app = angular.module('myApp', []);

app.controller('myCtrl', function($scope, serviceA, serviceB) {
    //to do
});

With such given function, the injector will judge the name of services by examining the function declaration and names of its parameters. As we can see here, we have 3 services to be injected I.e $scope, serviceA, serviceB.

The advantage of this type of annotation is that there is no headache of ordering the service names or keeping the parameters in sync with an array. You can reorder anytime. But the disadvantage is – if u simplify the service, would lead to service name change and will break the code.

Why Dependency Injection (DI)?

In software engineering, there are 3 ways where a component can use its dependencies. They are :

  • Using the ‘new’ operator, the component can create the dependency.
  • The component can refer to the dependency by using the global variable.
  • The component can have the dependency passed to it as a parameter.

Among the above-mentioned ways, first two points are not viable as dependencies and have to be hardcoded to the component. It makes difficult to modify the dependencies.

The third option is most applicable as the component is not concerned with dependency creation. The dependency is already created and handed to the component.

So basically with Dependency Injection, we are avoiding hard coding of dependencies, and tight coupling, thus maintaining the code across the application.

Next > Routing in AngularJS explained with an example.