Angular Dependency Injection Provider and Types of Provider

Angular Dependency Injection Provider
The Angular Dependency Injection provides several types of providers.
Class Provider : useClass
Value Provider: useValue
Factory Provider: useFactory
Aliased Class Provider: useExisting
useClass Provider
when you want to provide another class with your provider DI Token then we use useClass class provider
. This may be an instance of the same class or another class.
providers :[{ provide: StudentService, useClass: StudentService }]
The first argument provide
is DI Token or a Key.
The second argument useClass
: is a DI provider that takes a class. For this case token and provider (class name) are the same.
The Angular Provides a shortcut in cases where both token & class name matches as follows.
providers :[StudentService]
Example:
We created service : EmployeeService:
import { Injectable } from '@angular/core'; /* * Here we did not add providedIn: root (Will see later in same post - how * we use 'useClass' with providedIn) */ @Injectable() export class EmployeeService { printEmp(): string { return 'This is Permanent employee of Company'; } }
Case 1: To make it work we will add this service into providers. This is Simple.
providers: [EmployeeService],
Case 2: Now Let’s change the instance of this DI Token with some other class (we have created this class in the same app.module.ts file). This is a Simple Typescript class. Nothing is related to Angular.
// This is Simple Typescript class. Nothing is related to Angular export class OffShoreEmpService { printEmp(): string { return 'This is OffShore employee'; } } providers: [{provide: EmployeeService, useClass: OffShoreEmpService}],
Use of it in a Component.
export class HomeComponent implements OnInit { message: string = ''; constructor(private empService: EmployeeService) { } ngOnInit(): void { this.message = this.empService.printEmp(); } }
Outputs:
For case 1: a message is: ‘This is Permanent employee of Company’
For Case 2: a message is: ‘This is OffShore employee’
So injector is same in HomeComponent constructor function but the result is different for both cases.
useClass with providedIn
// This is simple Class export class OffShoreEmpService { printEmp() { console.log('This is OffShore employee'); } } @Injectable({ providedIn: 'root', useClass: OffShoreEmpService // Here we can useClass property to pass another Class }) export class EmployeeService { printEmp() { console.log('This is Permanent employee of Company'); } }
useFactory Provider
By using useFactory
, we can return instances or objects at runtime. This factory pattern is very powerful and gives you a lot of possibilities when it comes to cross-platform development.
Sometimes we add dependencies to the factory to decide whether to return ClassOne or ClassTwo. However, we can add the dependencies with the deps property
on the configuration object.
import { Injectable } from '@angular/core'; import { AuthService } from './auth.service'; // Class One : OffShoreEmpService export class OffShoreEmpService { printEmp() { console.log('This is OffShore employee'); } } // Class Two: OtherEmployee export class OtherEmployee { printEmp() { console.log('This is Other employee') } } // This is Factory function that return class instance at run time. // AuthService is dependency here that is optional export function EmpFactory(auth: AuthService) { // Based on isLoggedIn status - returning class object return auth.isLoggedIn() ? new OtherEmployee(): new OffShoreEmpService(); } @Injectable({ providedIn: 'root', useFactory: EmpFactory, deps: [AuthService] // AuthService is dependency here that is optional }) export class EmployeeService { constructor() { } printEmp() { console.log('This is Permanent employee of Company'); } }
Auth service (Used in above example)
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class AuthService { isLoggedIn() { return false; } }
useValue Provider
By using useValue
provider, we can return a single value.
@Injectable({ providedIn: 'root', useValue: { printEmp: () => 'See, This is JS mount', }, }) export class EmployeeService { empName = 'This is JS'; printEmp() { return this.empName; } }
useExisting Provider
By using useExisting
provider we can pass an already created service for a request token.
OffShoreEmpService – this service is already flowing into the angular application
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class OffShoreEmpService { printEmp(): string { return 'This is OffShore employee'; } }
Below is EmployeeService and we want to update this with our pre-existing service (created above)
So we will use here useExisting property.
import { Injectable } from '@angular/core'; import { OffShoreEmpService } from './off-shore-emp.service'; @Injectable({ providedIn: 'root', useExisting: OffShoreEmpService // Pass you already created service here. }) export class EmployeeService { printEmp() { return 'Thi is emp'; } }
What is the difference between useClass and useExisting?
- If we want to pass a class that is not in the application, then we can create that class and pass it with useClass provider. (Here Class may be simple Typescript Class)
- If there is already a service created then we can use useExisting provider. (Here service is Angular service created with @Injectable and providedIn)
If we use useClass for an already created service then what will happen?
In this case, two instances of the same service will be created and that is not acceptable.
Angular 9 https://www.jsmount.com/whats-new-in-angular-9/
Read here the official doc of Angular for Provider…
https://angular.io/guide/dependency-injection-providers
Angular Dependency Injection Provider
One thought on “Angular Dependency Injection Provider and Types of Provider”