繁体   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