Menu Close

Difference between Injector, @Injectable & @Inject in Angular

In this article we will learn about Difference between Injector, @Injectable & @Inject in Angular. The heart of the Angular Dependency injection system is the Angular Injector. We’ll examine it in more detail in this article. Additionally, we’ll examine the @Injectable & @Inject decorators. Please read the first article, Dependency Injection in Angular, before reading this one.

What is Angular Injector?

The Angular Injector is responsible for instantiating the dependency and injecting it into the component or service.

Using the injection token, the injector searches for the dependency in the Angular Providers. The Provider, which offers instructions on how to construct an instance of the dependency, is returned by the Angular Providers array. The instance is created by the injector and added to the component or service.

When is the Angular Injector created?

At the time of application bootstraps, Angular creates two Injector trees.

  • ModuleInjector tree– For Modules, The Angular loads the Root Module (named as AppModule) when the application bootstraps. It creates RootModule Injector for the Root Module. This Injector has an application-wide scope.
  • ElementInjector tree – For Elements (Components & Directives etc), Angular Root Module loads the AppComponent, which is the root component of our app. The AppComponent gets its own Injector. We call this root Injector. This Injector becomes the root of the ElementInjector tree.

Adding the service to the injector

We register all dependencies of the application with the Providers. Every injector has a Provider associated with it. The Providers metadata of @NgModule, @Component or @Directive is where we register our dependency.

  • The location where you register your dependency determines its scope. The Root Provider is attached to the dependency registered with the Module using the @NgModule decorator ( Provider attached to the Root Injector). The entire application can use this Dependency.
//We can Inject the services under this provider like below
providers: [ProductService, LoggerService, AdminService]

@Injectable in Angular

@Injectable() lets Angular know that a class can be used with the dependency injector. @Injectable() is not strictly required if the class has other Angular decorators on it or does not have any dependencies. What is important is that any class that is going to be injected with Angular is decorated. However, best practice is to decorate injectables with @Injectable(), as it makes more sense to the reader.

Example of Injectable

We’ve already created the ProductService, so let’s make a new one called LoggerService and see what the @Injectable() decorator is used for.

We have created the Logger Service like below,

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

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

  constructor() { }

  log(message:any) {
    console.log(message);
  }
}

Product Service

  • The ProductService has a dependency on the LoggerService. Hence it is decorated with the @Injectable decorator. Remove @Injectable() from ProductService and you will get the following error.
  • RemoveĀ @Injectable()Ā fromĀ LoggerServiceĀ will not result in any error as theĀ LoggerServiceĀ do not have any dependency.
import { Injectable } from '@angular/core';
import { Product } from '../class/product';
import { LoggerService } from './logger.service';

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

  products: Product[]=[];

  constructor(private loggerService: LoggerService) { 
    this.loggerService.log("Product Service Constructor Initialized");
  }

  getProductDetails(){
    this.loggerService.log("getProducts called");
    this.products = [
      new Product(1,'HP Spectre x360', 'HP Spectre x360 2-in-1 Laptop OLED Touch 13.5-ef0054TU.', 149999,'laptop.jpg'),
      new Product(2,'iPhone 13 Pro', 'Apple iPhone 13 Pro (256 GB) - Alpine Green', 119900,'mobile.jpg'),
      new Product(3,'SONY Camera', 'SONY ILCE-7M4K/BQIN5 Mirrorless Camera Single Lens: 28-70 mm  (Black)', 230990,'camera.png'),
      new Product(4,'SAMSUNG Crystal 4K', 'SAMSUNG Crystal 4K 138 cm (55 inch) Ultra HD (4K) LED Smart Tizen TV  (UA55AUE60AKLXL)', 45990,'tv.png'),
     ];
     this.loggerService.log(this.products);
     return this.products;
  }
}

Uncaught Error: Canā€™t resolve all parameters for ProductService

The injectable decorator also has theĀ ProvidedInĀ property using which you can specify how Angular should provide the dependency.

@Injectable({
  providedIn: 'root'
})

@Inject in Angular

The @Inject() is a constructor parameter decorator, which tells angular to Inject the parameter with the dependency provided in the given token. It is a manual way of injecting the dependency.

  • We can manually inject the LoggerService by using the @Inject decorator applied to the parameter loggerService as shown below.
  • The @Inject takes the Injector token as the parameter. The token is used to locate the dependency in the Providers.
export class ProductService {
  constructor(@Inject(LoggerService)  private loggerService: any) {
    this.loggerService.log("Product Service Constructor Initialized");
  }
}

@Inject() is a manual mechanism for letting Angular know that a parameter must be injected.

Conclusion

We discussed the difference between Injector, @Injectable & @Inject in Angular with considering some examples.

Leave behind your valuable queries and suggestions in the comment section below. Also, if you think this article helps you, do not forget to share this with your developer community. Happy Coding šŸ™‚

Related Articles

Jayant Tripathy
Coder, Blogger, YouTuber

A passionate developer keep focus on learning and working on new technology.

Leave a Reply

Your email address will not be published.