簡體   English   中英

typescript 中抽象 class 的多重實現,用於 Angular 依賴注入

[英]Multi implementation of an abstract class in typescript for Angular dependency injection

我有一個抽象的 class 和它的實現

export abstract class IPrint {
    abstract Print(textInput: string): void;
}

export class FilePrint implements IPrint {
    Print(textInput: string): void {
        console.log("File Print");
    }
}

接着介紹Angular DI:

  providers:
    [
      { provide: IPrint, useClass: FilePrint }
    ],

我可以像下面這樣使用它:

  constructor(private _print: IPrint) { }

  ngOnInit(): void {
    console.log(this._print.Print("HI"))
  }

現在我想要 IPrint 的多重實現

export class ScreenPrint implements IPrint {
    Print(textInput: string): void {
        console.log("Screen Print")
    }
}

接着介紹Angular DI:

  providers:
    [
      { provide: IPrint, useClass: FilePrint },
      { provide: IPrint, useClass: ScreenPrint }
    ],

當我想使用 IPrint 時,angular 不知道必須使用哪個實現:

constructor(private _print: IPrint) { }

angular 不知道必須使用哪個實現:

angular 知道。 Angular 將使用ScreenPrint 您只需覆蓋 IPrint 的注入令牌。 對於一個注入令牌,您一次不能有不同的實現。

我有類似的問題,並通過一個接口和一個 InjectionToken 列表來解決它。 這有點矯枉過正,但這提供了很大的靈活性,並且可以應用於其他問題。

在一個項目中,我們在一個共享模塊和每個組件提供的多個自定義實現中設置了一個全局打印服務。 並且無需在全局服務中顯式注入(因此引用)所有可能的實現。

接口和第一個實現

export interface IPrint {
    Print(textInput: string): void;
}

export class FilePrint implements IPrint {
    Print(textInput: string): void {
        console.log("File Print");
    }
}

使用 InjectionToken 創建服務實現列表

 // Keep list of token, provider will give a implementation for each of them
 export const PrintServiceTokens: Map<string, InjectionToken<IPrint>> = new Map();
 // Add File service implementation token
 PrintServiceTokens.set('file', new InjectionToken<IPrint>('file'));

提供者文件服務實現

   providers: [
      ...
      // First implementation service
      {
         provide: PrintServiceTokens.get('file'),
         useClass: FilePrint
      }
   ]

其他實現(可能在另一個模塊上)

export class ScreenPrint implements IPrint {
    Print(textInput: string): void {
        console.log("ScreenPrint");
    }
}

為其他實現添加令牌

PrintServiceTokens.set('screen', new InjectionToken<IPrint>('screen'));

添加提供商

   providers: [
      ...
      // Other implementation service
      {
         provide: PrintServiceTokens.get('screen'),
         useClass: ScreenPrint
      }
   ]

最后,在組件或服務中

    myPrintService: IPrint;

    constructor(private injector: Injector) {
       // Up to you to choose service to use, a simple string could be provided by a @Input
       this.myPrintService = this.injector.get(PrintServiceTokens.get('file'));
       this.myPrintService = this.injector.get(PrintServiceTokens.get('screen'));
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM