Dependency Injection Tokens in Angular
Dependency Injection Tokens (DI Tokens) in Angular are used to uniquely identify dependencies that are injected into components, directives, or services. They are particularly useful when injecting values, interfaces, or abstract classes.
Understanding DI Tokens
DI Tokens are a way to identify a dependency in Angular's dependency injection system. They can be strings, class types, or instances of the InjectionToken
class:
// string token example
{ provide: 'StringToken', useValue: 'Hello, world!' }
// class token example
class MyClass { }
{ provide: MyClass, useClass: MyClass }
// InjectionToken example
import { InjectionToken } from '@angular/core';
export const MY_TOKEN = new InjectionToken<string>('MyToken');
Using InjectionToken
The InjectionToken
class is used to create DI tokens that are type-safe and can be used with complex types:
// my-token.ts
import { InjectionToken } from '@angular/core';
export const CONFIG_TOKEN = new InjectionToken<Config>('ConfigToken');
export interface Config {
apiUrl: string;
timeout: number;
}
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { CONFIG_TOKEN, Config } from './my-token';
const config: Config = {
apiUrl: 'https://api.example.com',
timeout: 3000
};
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [
{ provide: CONFIG_TOKEN, useValue: config }
],
bootstrap: [AppComponent]
})
export class AppModule { }
// my-component.component.ts
import { Component, Inject } from '@angular/core';
import { CONFIG_TOKEN, Config } from '../my-token';
@Component({
selector: 'app-my-component',
template: '{{ config.apiUrl }} - {{ config.timeout }}',
})
export class MyComponent {
constructor(@Inject(CONFIG_TOKEN) public config: Config) { }
}
In this example, the CONFIG_TOKEN
is created using the InjectionToken
class. The configuration object is injected into the component using this token.
Benefits of Using InjectionToken
Using InjectionToken
provides several benefits:
- Type safety: Ensures that the injected value matches the expected type.
- Readability: Provides meaningful names for injected dependencies.
- Flexibility: Can be used for non-class dependencies like strings, objects, or interfaces.
Injecting Interface Dependencies
DI Tokens are particularly useful for injecting dependencies that are interfaces or abstract classes:
// logger.service.ts
export interface Logger {
log(message: string): void;
}
export class ConsoleLogger implements Logger {
log(message: string): void {
console.log('ConsoleLogger:', message);
}
}
export const LOGGER_TOKEN = new InjectionToken<Logger>('LoggerToken');
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { LOGGER_TOKEN, Logger, ConsoleLogger } from './logger.service';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [
{ provide: LOGGER_TOKEN, useClass: ConsoleLogger }
],
bootstrap: [AppComponent]
})
export class AppModule { }
// my-component.component.ts
import { Component, Inject } from '@angular/core';
import { LOGGER_TOKEN, Logger } from '../logger.service';
@Component({
selector: 'app-my-component',
template: '',
})
export class MyComponent {
constructor(@Inject(LOGGER_TOKEN) private logger: Logger) { }
logMessage() {
this.logger.log('Hello from MyComponent');
}
}
Key Points
- DI Tokens uniquely identify dependencies in Angular's DI system.
- The
InjectionToken
class provides a type-safe way to create tokens for complex types. - DI Tokens enhance readability, type safety, and flexibility when injecting dependencies.
- They are especially useful for injecting values, interfaces, or abstract classes.
Conclusion
Dependency Injection Tokens are a powerful feature in Angular's DI system. By using tokens, you can ensure type safety, improve code readability, and inject complex dependencies with ease. Understanding and utilizing DI Tokens will enhance your ability to manage dependencies in Angular applications effectively.