Dependency Injection in Angular - Redvike
14 January 2019

Dependency Injection in Angular

14 January 2019

Dependency Injection in Angular

Author:

Avatar
Jan Michalak
14 January 2019

Dependency Injection in Angular

Author:

Avatar
Jan Michalak

Introduction

So, Dependency Injection is a Design Pattern which became really popular in software development recently, mostly because of Java developers, but it’s also commonly used by C, .NET, Php and of course by JavaScript developers.

The Angular team has extensively used Dependency Injection pattern since the first versions, and in the new implementation of Angular which is Angular 2+ they went even further with this concept.

In this article, I will cover what Dependency Injection is, when is it helpful and when not as well as show the different types of Dependency Injection implementations in JavaScript.

Simple explanation of what Dependency Injection is?

First things first, let me explain in the simplest way possible what the Dependency Injection is. Most concepts are easier to understand based on real life example instead of theory so let’s imagine you are gamepad architect.

In a gamepad, you have stuff like thumb joysticks, buttons, a battery and so on. Those elements are injected into a gamepad.

Imagine a situation when you have a gamepad which has a battery with a low capacity of energy injected in it, and you want to upgrade it to a better one. So, the only thing you are doing is changing batteries, but the gamepad is still working the same way. The implementation of the gamepad hasn’t changed. Alternatively, maybe you want to replace the buttons with ones that blink on every press. Still, the gamepad is working the same way, but you have an extra feature – blinking buttons.

xbox pad parts

Now let’s see how the idea of Dependency Injection may look in software development.

class MyApp {
  constructor () {
    this.notifyService = new SmsNotificationService();
  }

  notifyUser() {
    this.notifyService.notify();
  }
}

In the example above we have the “MyApp” class which uses SmsNotificationService to notify the user, but it’s not declared in a Dependency Injection way. In some cases it’s ok, but when we have dozens of classes which need access to notification service, and we want to replace SmsNotificationService to EmailNotificationService then the refactor process can become really painful.

class MyApp {
  constructor (NotificationService) {
    this.notifyService = NotificationService;
  }

  notifyUser() {
    this.notifyService.notify();
  }
}

In cases like that Dependency Injection becomes really helpful. We can easily replace our service without replacing much code. This is one of the most important reasons to use Dependency Injection in our code.

Another significant advantage of implementing Dependency Injection is testing. Let’s say we would like to test the “MyApp” class. We probably don’t want to send notifications to our users while tests are running because at that moment we don’t really care how our service is working since we should test only one thing at once. Solution? We can use our Dependency Injection framework to inject a mock service which will pretend to be a real one.

Dependency Injection Types

We can implement Dependency Injection in a variety of ways and here are some of them:

Constructor Injector

class MyApp {
  constructor (NotificationService) {
    this.notifyService = NotificationService;
  }
 
  notifyUser() {
    this.notifyService.notify();
  }
}
 
const service = new NotificationService();
const app = new MyApp(service);

Setter Injection

In this type, we are passing our dependency when we initialise our class. This approach is really simple to implement, but it has one downside. Services that we want to inject into a class may have their own dependencies as well, and we need to remember about this.

class MyApp {
  setNotificationService (NotificationService) {
    this.notifyService = NotificationService;
  }
 
  notifyUser() {
    this.notifyService.notify();
  }
}
 
const service = new NotificationService();
const app = new MyApp();unspl
app.setNotificationService(service);

In this approach, the dependency is injected by passing to the setter method of Class which needs to use it.

AngularJS

All of the examples presented above have their downsides with usability, reusability and complex testing. So in big projects is nice to have a Dependency Injection framework which handles the injection of our dependencies out of the box, so we don’t have to worry if we forget about including something. Here’s the idea that the AngularJS team has come up with:

const app = angular.module('app', []);
myApp.service('NotificationService', function () {
  this.notify = function () {
  // Send notification
  }
});

myApp.controller('MyAppController', function (NotificationService) {
  this.notifyUser = function () {
    NotificationService.notify();
  }
});

In AngularJS we first need to register our dependency like in the example above. We are registering a service of NotificationService. This way in AngularJS we can register value, factory, provider and constant as well as service. So they can be injected into each other as dependencies.

To inject a dependency, the only one thing we have to remember about is to provide the name of what we want to inject as the function parameter. In this example, we are injecting the NotificationService into MyAppController, so while initialising this controller, we have to set the name of notification service as a function parameter so that we can use the notification function inside of the controller.

As you can see the benefit of using Dependency Injection framework is that we only have to bother to register our dependency and then in a flexible way we can reuse it anywhere, and let AngularJS handle the rest.

Summary

I believe now you have a basic idea of what Dependency Injection is, how it works, how you can use it in your project and why Dependency Injection frameworks are really helpful. Moreover, I hope now it will be easier to understand next part of this article in which I will dig deeper into Dependency Injection patterns and techniques especially in Angular +2.

AngularJS
Injection
Injections
JavaScript

Related blog posts

Interested? - let us know ☕
[email protected] Get Estimation