0
0
Angularframework~5 mins

Multi-provider pattern in Angular

Choose your learning style9 modes available
Introduction

The multi-provider pattern lets you register many services under the same token. Angular then gives you all of them as a list. This helps when you want to add features without changing existing code.

You want to add multiple logging services that all run together.
You have several data transformers and want to apply them all in order.
You want to register many validators for a form and run them all.
You want to provide multiple strategies for a feature and pick them dynamically.
You want to extend functionality by adding new providers without modifying the original provider.
Syntax
Angular
providers: [
  { provide: TOKEN, useClass: ServiceA, multi: true },
  { provide: TOKEN, useClass: ServiceB, multi: true }
]

Set multi: true to tell Angular this token has multiple providers.

Angular injects an array of all providers registered with that token.

Examples
This registers two logger services under the same token 'LOGGERS'. Injecting 'LOGGERS' gives an array of both loggers.
Angular
providers: [
  { provide: 'LOGGERS', useClass: ConsoleLogger, multi: true },
  { provide: 'LOGGERS', useClass: FileLogger, multi: true }
]
Angular's HTTP client uses this pattern to apply multiple interceptors in order.
Angular
providers: [
  { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
  { provide: HTTP_INTERCEPTORS, useClass: CacheInterceptor, multi: true }
]
Sample Program

This example shows two greeter services registered under the same token GREETERS using multi-provider. The component injects all greeters as an array and displays their greetings.

Angular
import { Component, Inject, Injectable, InjectionToken } from '@angular/core';
import { CommonModule } from '@angular/common';

const GREETERS = new InjectionToken<{greet(): string}>('GREETERS');

@Injectable()
class EnglishGreeter {
  greet() { return 'Hello'; }
}

@Injectable()
class SpanishGreeter {
  greet() { return 'Hola'; }
}

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule],
  template: `<div *ngFor="let greeter of greeters">
               {{ greeter.greet() }}
             </div>`,
  providers: [
    { provide: GREETERS, useClass: EnglishGreeter, multi: true },
    { provide: GREETERS, useClass: SpanishGreeter, multi: true }
  ]
})
export class AppComponent {
  constructor(@Inject(GREETERS) public greeters: { greet(): string }[]) {}
}
OutputSuccess
Important Notes

Without multi: true, Angular would overwrite previous providers for the same token.

Use multi-providers to keep code modular and easily extendable.

Summary

Multi-provider pattern lets you register many providers under one token.

Angular injects an array of all providers registered with that token.

This pattern helps add features without changing existing code.