providers: [
{
provide: CheckoutDeliveryService,
useClass: MockCheckoutDeliveryService,
},

provider使用一個DI token配置injector,後者使用該token建立一個具體的能用于運作時的執行個體,該執行個體可以注入到Component,指令,管道和其他服務裡。
下列兩種寫法等價:
providers: [Logger]
[{ provide: Logger, useClass: Logger }]
provide字段:holds the token that serves as the key for both locating a dependency value and configuring the injector.
存儲了一個token,作為定位一個依賴值和配置injector的key.
第二個值是provider definition object,provider的定義對象,告訴injector如何建立被依賴的值。除了useClass之外,還有useExisting, useValue, useFactory等等。
The second property is a provider definition object, which tells the injector how to create the dependency value. The provider-definition key can be useClass, as in the example. It can also be useExisting, useValue, or useFactory. Each of these keys provides a different type of dependency, as discussed below.
不同的class可以provide同一個服務。
下列代碼的含義是,如果有代碼需要一個Logger,那麼傳回一個BetterLogger執行個體。
[{ provide: Logger, useClass: BetterLogger }]
看下面這段代碼:
@Injectable()
export class EvenBetterLogger extends Logger {
constructor(private userService: UserService) { super(); }
log(message: string) {
const name = this.userService.user.name;
super.log(`Message to ${name}: ${message}`);
}
}
正确的injector配置方式:
[ UserService,
{ provide: Logger, useClass: EvenBetterLogger }]
Value providers
有時我們也可以讓injector傳回一個事先準備好的對象,即value provider的配置。
比如下面這個對象:
// An object in the shape of the logger service
function silentLoggerFn() {}
export const SilentLogger = {
logs: ['Silent logger says "Shhhhh!". Provided via "useValue"'],
log: silentLoggerFn
};
使用useValue傳回這個對象:
[{ provide: Logger, useValue: SilentLogger }]
如何隻注入一個簡單的字元串呢?
export const HERO_DI_CONFIG: AppConfig = {
apiEndpoint: 'api.heroes.com',
title: 'Dependency Injection'
};
TypeScript裡的接口是一個design time的概念,而DI架構需要一個運作時載體即DI token,是以接口并不能直接參與到
Angular的DI中去。
解決方案1
在NgModule裡提供和注入configuration對象:
providers: [
UserService,
{ provide: APP_CONFIG, useValue: HERO_DI_CONFIG }
],
解決方案2
使用InjectionToken object.
import { InjectionToken } from '@angular/core';
export const APP_CONFIG = new InjectionToken<AppConfig>('app.config');
現在就可以注冊依賴了:
providers: [{ provide: APP_CONFIG, useValue: HERO_DI_CONFIG }]
在任何構造函數裡可以使用這個依賴:
constructor(@Inject(APP_CONFIG) config: AppConfig) {
this.title = config.title;
}