Swiftorial Logo
Home
Swift Lessons
Matchups
CodeSnaps
Tutorials
Career
Resources

Multi-Providers in Angular

Multi-Providers in Angular allow you to provide multiple values for a single token. This is particularly useful for creating extensible features such as logging, middleware, or plugins where multiple implementations need to be aggregated.

Understanding Multi-Providers

To use multi-providers, you define a token and specify that it should use multiple providers by setting the multi property to true:

// logging.service.ts
import { InjectionToken } from '@angular/core';

export const LOGGING_TOKEN = new InjectionToken<string[]>('LoggingToken');

Providing Multiple Values

To provide multiple values for a single token, use the multi: true option in the provider configuration:

// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { LOGGING_TOKEN } from './logging.service';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule],
  providers: [
    { provide: LOGGING_TOKEN, useValue: 'LogEntry1', multi: true },
    { provide: LOGGING_TOKEN, useValue: 'LogEntry2', multi: true },
    { provide: LOGGING_TOKEN, useValue: 'LogEntry3', multi: true }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Injecting Multiple Values

When you inject the token into a component or service, Angular will provide an array containing all the values:

// my.component.ts
import { Component, Inject } from '@angular/core';
import { LOGGING_TOKEN } from './logging.service';

@Component({
  selector: 'app-my-component',
  template: '
{{ log }}
', }) export class MyComponent { constructor(@Inject(LOGGING_TOKEN) public logs: string[]) { } }

In this example, the logs array in the component will contain ['LogEntry1', 'LogEntry2', 'LogEntry3'].

Using Multi-Providers with Classes

Multi-providers can also be used with class providers, allowing multiple implementations of an interface to be injected:

// notification.service.ts
export interface Notification {
  send(message: string): void;
}

export class EmailNotification implements Notification {
  send(message: string): void {
    console.log('Email: ' + message);
  }
}

export class SMSNotification implements Notification {
  send(message: string): void {
    console.log('SMS: ' + message);
  }
}

export const NOTIFICATION_TOKEN = new InjectionToken<Notification[]>('NotificationToken');

// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { NOTIFICATION_TOKEN, EmailNotification, SMSNotification } from './notification.service';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule],
  providers: [
    { provide: NOTIFICATION_TOKEN, useClass: EmailNotification, multi: true },
    { provide: NOTIFICATION_TOKEN, useClass: SMSNotification, multi: true }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

// my.component.ts
import { Component, Inject } from '@angular/core';
import { NOTIFICATION_TOKEN, Notification } from '../notification.service';

@Component({
  selector: 'app-my-component',
  template: '',
})
export class MyComponent {
  constructor(@Inject(NOTIFICATION_TOKEN) private notifications: Notification[]) { }

  sendNotifications() {
    this.notifications.forEach(notification => notification.send('Hello!'));
  }
}

In this example, both EmailNotification and SMSNotification will be injected and used to send notifications.

Key Points

  • Multi-Providers allow multiple values for a single token.
  • They are useful for extensible patterns like logging, middleware, or plugins.
  • Use the multi: true option in the provider configuration to enable multi-providers.
  • Injected values are available as an array, which can contain strings, objects, or class instances.

Conclusion

Multi-Providers in Angular provide a powerful way to manage multiple values or implementations for a single token. By using multi-providers, you can create flexible and extensible features in your Angular applications. Understanding and leveraging multi-providers will help you build more modular and maintainable code.