Angular 4 依賴注入教程之四 FactoryProvider的使用typescript
Angular 4 依賴注入教程之五 FactoryProvider配置依賴對象shell
Angular 4 依賴注入教程之六 Injectable 裝飾器bootstrap
Angular 4 依賴注入教程之七 ValueProvider的使用segmentfault
本系列教程的開發環境及開發語言:app
Console 對象能夠在任何全局對象中訪問,如 Window
,WorkerGlobalScope
以及經過屬性工做臺提供的特殊定義。在瀏覽器中咱們能夠經過 Window.console
訪問 console
對象,使用示例以下:
console.log('My nickname is semlinker');
FactoryProvider 用於告訴 Injector (注入器),經過調用 useFactory
對應的函數,返回 Token
對應的依賴對象。
export interface FactoryProvider { // 用於設置與依賴對象關聯的Token值,Token值多是Type、InjectionToken、 // OpaqueToken的實例或字符串 provide: any; // 設置用於建立對象的工廠函數 useFactory: Function; // 依賴對象列表 deps?: any[]; // 用於標識是否multiple providers,如果multiple類型,則返回與Token關聯的依賴 // 對象列表 multi?: boolean; }
在 FactoryProvider的使用 這篇文章中,咱們已經介紹了 FactoryProvider
的一些相關知識。接下來咱們將介紹如何使用 FactoryProvider
配置依賴對象。
俗話說得好,溫故而知新。咱們先來回顧一下上一節建立的 LoggerService
服務:
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 { }
在繼續介紹前,咱們先來了解一下 Angular
的一大特點:
跨平臺開發
學習如何基於 Angular 構建應用程序,並複用代碼和技能來構建適用於全部平臺的應用。好比:Web應用、移動Web應用、原生移動應用和原生桌面應用等。
沒錯,Angular
框架的一大特點就是跨平臺開發。回到正題,不知道讀者有沒有察覺到,在 LoggerService
類中的 log()
方法內,咱們是直接使用 console.log()
方法輸出調試信息。雖然在大多數狀況下,咱們的應用都是運行在瀏覽器環境下,但 console.log()
存在兼容性問題 (瞭解詳細信息 - Can I Use)。除此以外,假如往後咱們的應用須要運行在其它平臺下,就會出現問題。
爲了解決上述問題,咱們能夠建立一個 ConsoleService
服務,且該服務需實現統一的 Console
接口。但本文的重點不在這裏,所以咱們先簡單實現一個 ConsoleService
服務:
export class ConsoleService { log(message) { console.log(`ConsoleService: ${message}`); } }
接下來咱們就須要更新先前的 LoggerService
服務:
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.
這說明提供的參數與調用目標的簽名不匹配,這是由於在 AppModule
中,LoggerService
的配置方式是:
{ provide: LoggerService, useFactory: () => { return new LoggerService(true); }
而此時 LoggerService
構造函數輸入參數的個數爲兩個,所以會拋出上面的異常。那麼咱們應該怎麼解決這個問題呢?這時咱們就要利用 FactoryProvider
接口中定義的 deps
屬性,來聲明 LoggerService
所依賴的對象。
{ provide: LoggerService, useFactory: (consoleService) => { return new LoggerService(true, consoleService); }, deps: [ConsoleService] }
@NgModule({ ..., providers: [ HeroService, ConsoleService, { provide: LoggerService, useFactory: (consoleService) => { return new LoggerService(true, consoleService); }, deps: [ConsoleService] } ], bootstrap: [AppComponent] }) export class AppModule { }
當更新完代碼,而後再來一個華麗的保存操做,最後打開你的控制檯,你又看到預期的輸出信息:
LoggerService: Fetching heros...
在現實生活中,工廠是用來生產產品的,如鞋子工廠用來生產鞋子。而 FactoryProvider
接口中 useFactory
屬性對應的工廠函數就是用來建立依賴對象。此外生產一雙鞋子也須要對應的材料,如鞋底、鞋帶等,而建立依賴對象也可能須要依賴其它對象,所以 FactoryProvider
接口中定義了 deps
屬性用來聲明依賴對象列表。