Angular 4 依賴注入教程之五 FactoryProvider配置依賴對象

目錄

閱讀須知

本系列教程的開發(fā)環(huán)境及開發(fā)語言:

基礎(chǔ)知識

Console 對象

Console 對象可以在任何全局對象中訪問,如 WindowWorkerGlobalScope 以及通過屬性工作臺提供的特殊定義。在瀏覽器中我們可以通過 Window.console 訪問 console 對象,使用示例如下:

console.log('My nickname is semlinker');

FactoryProvider 的作用

FactoryProvider 用于告訴 Injector (注入器),通過調(diào)用 useFactory 對應(yīng)的函數(shù),返回 Token 對應(yīng)的依賴對象。

FactoryProvider 接口

export interface FactoryProvider {
  // 用于設(shè)置與依賴對象關(guān)聯(lián)的Token值,Token值可能是Type、InjectionToken、
  // OpaqueToken的實例或字符串
  provide: any;
  // 設(shè)置用于創(chuàng)建對象的工廠函數(shù)
  useFactory: Function;
  // 依賴對象列表
  deps?: any[];
  // 用于標識是否multiple providers,若是multiple類型,則返回與Token關(guān)聯(lián)的依賴
  // 對象列表
  multi?: boolean;
}

FactoryProvider的使用 這篇文章中,我們已經(jīng)介紹了 FactoryProvider 的一些相關(guān)知識。接下來我們將介紹如何使用 FactoryProvider 配置依賴對象。

FactoryProvider

俗話說得好,溫故而知新。我們先來回顧一下上一節(jié)創(chuàng)建的 LoggerService 服務(wù):

export class LoggerService {
    constructor(private enable: boolean) { }

    log(message: string) {
        if(this.enable) {
           console.log(`LoggerService: ${message}`);
        }
    }
}

LoggerService 的正確配置方式如下:

@NgModule({
   ...,
   providers: [
     HeroService,
     {
      provide: LoggerService, 
      useFactory: () => {
        return new LoggerService(true);
      }
    }
   ],
  bootstrap: [AppComponent]
})
export class AppModule { }

在繼續(xù)介紹前,我們先來了解一下 Angular 的一大特色:

跨平臺開發(fā)

學習如何基于 Angular 構(gòu)建應(yīng)用程序,并復(fù)用代碼和技能來構(gòu)建適用于所有平臺的應(yīng)用。比如:Web應(yīng)用、移動Web應(yīng)用、原生移動應(yīng)用和原生桌面應(yīng)用等。

沒錯,Angular 框架的一大特色就是跨平臺開發(fā)?;氐秸},不知道讀者有沒有察覺到,在 LoggerService 類中的 log() 方法內(nèi),我們是直接使用 console.log() 方法輸出調(diào)試信息。雖然在大多數(shù)情況下,我們的應(yīng)用都是運行在瀏覽器環(huán)境下,但 console.log() 存在兼容性問題 (了解詳細信息 - Can I Use)。除此之外,假如日后我們的應(yīng)用需要運行在其它平臺下,就會出現(xiàn)問題。

為了解決上述問題,我們可以創(chuàng)建一個 ConsoleService 服務(wù),且該服務(wù)需實現(xiàn)統(tǒng)一的 Console 接口。但本文的重點不在這里,因此我們先簡單實現(xiàn)一個 ConsoleService 服務(wù):

export class ConsoleService {
    log(message) {
        console.log(`ConsoleService: ${message}`);
    }
}

接下來我們就需要更新先前的 LoggerService 服務(wù):

export class LoggerService {
    constructor(private enable: boolean,
      consoleService: ConsoleService) { }

    log(message: string) {
        if (this.enable) {
            console.log(`LoggerService: ${message}`);
        }
    }
}

但當我們更新完 LoggerService ,成功保存后,你會看到以下異常信息:

app.module.ts (27,16): Supplied parameters do not match any signature of call target.

這說明提供的參數(shù)與調(diào)用目標的簽名不匹配,這是因為在 AppModule 中,LoggerService 的配置方式是:

{
  provide: LoggerService, 
  useFactory: () => {
    return new LoggerService(true);
}

而此時 LoggerService 構(gòu)造函數(shù)輸入?yún)?shù)的個數(shù)為兩個,因此會拋出上面的異常。那么我們應(yīng)該怎么解決這個問題呢?這時我們就要利用 FactoryProvider 接口中定義的 deps 屬性,來聲明 LoggerService 所依賴的對象。

配置 deps 屬性

{
  provide: LoggerService, 
  useFactory: (consoleService) => {
    return new LoggerService(true, consoleService);
  },
  deps: [ConsoleService]
}

更新 AppModule

@NgModule({
   ...,
   providers: [
     HeroService,
     ConsoleService,
     {
      provide: LoggerService, 
      useFactory: (consoleService) => {
        return new LoggerService(true, consoleService);
      },
      deps: [ConsoleService]
    }
   ],
  bootstrap: [AppComponent]
})
export class AppModule { }

當更新完代碼,然后再來一個華麗的保存操作,最后打開你的控制臺,你又看到預(yù)期的輸出信息:

LoggerService: Fetching heros...

我有話說

工廠函數(shù)是用來干嘛的?

在現(xiàn)實生活中,工廠是用來生產(chǎn)產(chǎn)品的,如鞋子工廠用來生產(chǎn)鞋子。而 FactoryProvider 接口中 useFactory 屬性對應(yīng)的工廠函數(shù)就是用來創(chuàng)建依賴對象。此外生產(chǎn)一雙鞋子也需要對應(yīng)的材料,如鞋底、鞋帶等,而創(chuàng)建依賴對象也可能需要依賴其它對象,因此 FactoryProvider 接口中定義了 deps 屬性用來聲明依賴對象列表。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容