Home Angular Tutorials Angular Injector , @Injectable & @Inject

Angular Injector , @Injectable & @Inject

by aouidane.med.amine
143,299 views 20 min read

In this tutorial, we will delve deeper into the concepts of the Angular injector, including how to use the @Injectable and @Inject decorators.

We will learn about the role of the injector in dependency injection system and how it is used to instantiate objects and resolve dependencies.

We will also explore various scenarios in which you might use these decorators and gain a better understanding of how they work under the hood.

By the end of this tutorial, you should have a solid grasp on the concepts of the Angular injector and be able to use it effectively in your own projects.

Table of Contents

What is Angular Injector ?

In Angular, an injector is a service that is responsible for instantiating objects and resolving dependencies.

It is a hierarchical tree of injectors, with a root injector at the top that is created by the Angular framework. Each Angular component has its own injector, and the injector hierarchy reflects the component tree.

The injector is used to resolve and instantiate objects that are specified as dependencies for other objects. When an object depends on another object, it specifies that dependency using a DI Token.

The injector then uses the token to look up the dependency in its internal map and return the corresponding object instance.

For example, consider a component that depends on a service:

				
					@Component({
  selector: 'app-example',
  template: '<h1>{{ title }}</h1>'
})
export class ExampleComponent {
  constructor(private myService: MyService) {
    this.title = this.myService.getTitle();
  }
}

				
			

In this example, the ExampleComponent has a dependency on the MyService service.

The ExampleComponent specifies this dependency by including a private field of type MyService in its constructor.

When the injector instantiates the ExampleComponent, it will resolve the MyService dependency by looking up an instance of MyService in its internal map and passing it to the component’s constructor.

The injector is a powerful and flexible service that is at the heart of the dependency injection mechanism in Angular.

It allows you to specify dependencies declaratively, rather than having to create and manage them manually, which can make your code easier to write, maintain, and test.

Angular Injector internal map

In Angular, the injector maintains an internal map of object instances that it has created or retrieved from providers.

This map is used to store and retrieve objects that are specified as dependencies for other objects.

The injector uses the Token of a dependency to look up the corresponding object instance in its internal map.

If it cannot find an instance for the specified token, it will create one using the information provided by a provider, and then add it to the internal map.

The internal map allows the injector to store and retrieve object instances efficiently, without having to recreate them each time they are needed.

It also allows the injector to manage the life cycle of objects, ensuring that they are created and destroyed as needed based on the lifetime of the objects and the components that depend on them.

Angular Injector Types

In Angular, an injector is a service that is responsible for instantiating objects and resolving dependencies.

There are four types of injectors in Angular:

Platform injector

Allows you to register a service with the platform injector, which is the injector that is created for the root component of the application.

This can be useful if you have multiple Angular applications running on the same page, they will all share the same platform injector and any services that are registered with it.

Root injector

Allows you to register a service with the root injector, which means that the service will be available for injection in any part of your application.

This can be useful if you have a service that needs to be shared across multiple components  or modules (rootModule , sharedModule , featureModule …)

Module injector

This is the root injector for an Angular application, and it is created by the Angular framework when the application bootstraps. It is responsible for instantiating the root component of the application and providing dependencies for the entire application.

Element injector

This is an injector that is associated with a specific component or element in the component tree.

Each Angular component has its own injector, which is created by the parent injector when the component is instantiated.

The element injector is responsible for providing dependencies for the component and its children.

Angular Injector Hierarchy

In Angular, the injector is a hierarchical tree of injectors, with a root injector at the top that is created by the Angular framework.

Each Angular component has its own injector, which is created by the parent injector when the component is instantiated.

The injector hierarchy reflects the component tree, with the root injector at the top and element injectors for each component below it.

angular Injector hierachy

The injector hierarchy allows you to specify dependencies at different levels of the component tree and have them resolved in the appropriate context.

For example, you might specify a service as a dependency for a root component, which would make it available to all of the components in the application ( ParentComponent X , ChildComponent-A , ChildComponent-B , ChildComponent-A-X)

Alternatively, you might specify a service as a dependency for a child component, which would make it available only to that component and its children.

@Injectable Decorator

In Angular, the @Injectable decorator is used to create a service that can be injected into other components or services via the Angular dependency injection system

It’s important to note that the @Injectable decorator is only needed for services that are going to be injected into other components or services.

Services that are not going to be injected do not need to be decorated with @Injectable.

Here is an example of how to use the @Injectable decorator to create a service:

				
					import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class MyService {
  constructor() { }

  // service methods go here
}

				
			

The @Injectable decorator can take an optional metadata object that can be used to configure the service.

In the example above, the providedIn property is set to 'root', which means that this service will be available for injection throughout the entire application.

Once the service has been created, it can be injected into other components or services using Angular’s dependency injection system.

For example:

				
					import { Component } from '@angular/core';
import { MyService } from './my.service';

@Component({
  selector: 'app-my-component',
  templateUrl: './my-component.component.html',
  styleUrls: ['./my-component.component.css']
})
export class MyComponent {
  constructor(private myService: MyService) { }

  // component methods go here
}

				
			

In this example, the MyService is injected into the MyComponent using the constructor. The myService property will then be available for use within the component.

@Inject Decorator

The @Inject decorator is used in Angular to specify a dependency that should be injected into a constructor or a class property.

It allows you to specify a custom token for the dependency, which can be used to identify the dependency when it is being injected.

Here is an example of how to use the @Inject decorator:

				
					import { Inject } from '@angular/core';

export class MyClass {
  constructor(@Inject('MyToken') private myDependency: MyDependency) { }
}

				
			

In this example, the @Inject decorator is used to specify that the MyClass constructor requires an instance of MyDependency to be injected.

The 'MyToken' parameter is a token that is used to identify the dependency that should be injected.

It’s important to note that the @Inject decorator is only needed if you want to specify a custom token for the dependency that is being injected.

If you are injecting a dependency using its type (i.e. its class or interface), you do not need to use the @Inject decorator.

You can also use the @Inject decorator to inject dependencies using the manual way of the DI system.

When using the regular dependency injection system, the @Injectable decorator must be added to a service in order to inject it into another component or service. However, the @Inject decorator can be used to inject a service even if it does not have the @Injectable decorator.

References and Links

You may also like