从库注入器错误扩展 angular class

Extending angular class from library injector error

这个问题一般是关于扩展或替换组件库中的组件。我将使用一个这样的例子。我们有一个跨项目使用的组件库,其中包含许多 UI 组件和指令。这些组件会即时翻译自己。小部件获得注入其中的翻译服务,程序员指定他们想要翻译的键。这里一切都好。

假设这个基础翻译服务有方法 getTranslation() 来保持简单。

对于我们的大多数产品,基础翻译服务开箱即用。对于其他人,他们想使用不同的版本。我的第一个想法是定义一个接口和基础翻译/其他项目的服务实现它(对于 Spring Java 人来说是正常的)。我正在阅读 angular 风格指南 'Consider using a class instead of an interface'。我研究了一段时间以了解原因(因为我的背景是 Java),这似乎是有道理的 Angular DI 注入的工作方式不同 https://github.com/angular/angular/issues/19632

因此,作为测试,我在示例项目中创建了一个子类。

import { Injectable } from '@angular/core';
import { BaseTranslationService } from './base-translation.service';

@Injectable()
export class MyTranslationService extends BaseTranslationService {

  constructor() {
    super();
  }

  getTranslation(bundle: string, key: string, params?: any[]): string {

    let translation = super.getTranslation(bundle, key, params);
    return translation + ' from subclass';
  }
}

虽然在基础翻译服务上还有许多其他方法,但我只是想用一些沙箱内容覆盖上面的方法以进行此测试。

最后,在消费项目中,我知道不再提供 BaseTranslationService 而是提供新的:

providers: [ MyTranslationService, etc ]

这不起作用。我在所有需要 BaseTranslationService 的组件上收到此错误:

NullInjectorError: 没有 BaseTranslationService 的提供者!

看来 DI 不理解 MyTranslationService 是否适用于 BaseTranslationService。

这应该有效吗?我设置不正确吗?我是否误解了风格指南?

库中的组件查找使用令牌 BaseTranslationService 提供的服务。但是你没有这样的令牌了。你需要这个:

providers: [ { provide: BaseTranslationService, useClass: MyTranslationService}, etc ]

根据评论更新,您应该使用 @Injectable 装饰器注释 class MyTranslationService,如下所示,

@Injectable()
export class MyTranslationService extends BaseTranslationService {
...
}