Angular 4 依賴注入教程之三 ClassProvider的使用

目錄

閱讀須知

本系列教程的開發環境及開發語言:服務器

基礎知識

Provider 的做用

在 Angular 中咱們經過 Provider 來描述與 Token 相關聯的依賴對象的建立方式。在 Angular 中依賴對象的建立方式分爲如下四種:

  • useClass

  • useValue

  • useExisting

  • useFactory

angular-provider

(圖一:注入器、Provider與依賴對象關係)

Provider 的分類

在 Angular 中 Provider 主要分爲:

  • TypeProvider

  • ClassProvider

  • ValueProvider

  • ExistingProvider

  • FactoryProvider

ClassProvider

ClassProvider 接口定義

export interface ClassProvider {
  // 用於設置與依賴對象關聯的Token值,Token值多是Type、InjectionToken、
  // OpaqueToken的實例或字符串
  provide: any; 
  useClass: Type<any>;
  // 用於標識是否multiple providers,如果multiple類型,則返回與Token關聯的依賴
  // 對象列表
  multi?: boolean; 
}

看完上面的接口定義,相信一些讀者會以爲陌生。在本系列教程第二小節中,咱們用到了 TypeProvider。不信你往下看:

@NgModule({
  ...
  providers: [HeroService], // 方式一
  bootstrap: [AppComponent]
})
export class AppModule { }

// TypeProvider接口
export interface TypeProvider extends Type<any> {}

那跟 ClassProvider 有什麼關係?先不急,請你繼續往下看:

@NgModule({
  ...
  providers: [{
    provide: HeroService, useClass: HeroService // 方式二
  }],
  bootstrap: [AppComponent]
})
export class AppModule { }

是否是終於看到了 useClass 。其實上面兩種方式是等價的,方式一更加簡潔,方式二是採用標準的語法哈。那麼問題來了,何時要使用 useClass 語法?回答這個問題前,咱們先看個需求。

假設因爲業務須要,先前咱們定義的 HeroService 的數據,須要從服務器獲取,而不是使用靜態數據。項目採用先後端分離的開發方式進行開發,此外在項目開發前已經協商好數據格式,也給出了對應的模擬數據(測試數據)。

那麼除了修改原有的 HeroService 服務外,有沒有其它方式能夠方便地驗證一下模擬數據,同時保持較小的改動量哈。其實咱們能夠建立一個新的數據服務,如 MockHeroService ,具體實現以下:

建立 MockHeroService 服務

export class MockHeroService {
    heros: Array<{ id: number; name: string }> = [
        { id: 16, name: 'RubberMan' },
        { id: 17, name: 'Dynama' },
        { id: 18, name: 'Dr IQ' },
        { id: 19, name: 'Magma' },
        { id: 20, name: 'Tornado' }
    ];

    getHeros() {
        return this.heros;
    }
}

使用 MockHeroService 服務

@NgModule({
  ...
  providers: [{
    provide: HeroService, useClass: MockHeroService
  }],
  bootstrap: [AppComponent]
})
export class AppModule { }

更新完相關的代碼,正常狀況下,在 http://localhost:4200/ 頁面,你將看到如下的內容:

ID: 16 - Name: RubberMan
ID: 17 - Name: Dynama
ID: 18 - Name: Dr IQ
ID: 19 - Name: Magma
ID: 20 - Name: Tornado

其實服務命名爲 MockHeroService 的目的,也是爲了說明依賴注入的好處,即易於進行本地單元測試。此外假設沒有利用 Angular 依賴注入的特性,咱們須要修改應用中每一個應用到 HeroService 的地方。

我有話說

ClassProvider 接口中的 Type 類型是什麼?

export interface Type<T> extends Function { new (...args: any[]): T; }

export function isType(v: any): v is Type<any> {
  return typeof v === 'function';
}
相關文章
相關標籤/搜索