天天看點

Angular依賴注入官方文檔的學習筆記Value providers解決方案1解決方案2

providers: [
        {
          provide: CheckoutDeliveryService,
          useClass: MockCheckoutDeliveryService,
        },      
Angular依賴注入官方文檔的學習筆記Value providers解決方案1解決方案2

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'
};      
Angular依賴注入官方文檔的學習筆記Value providers解決方案1解決方案2

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;
}
      

繼續閱讀