扩展已注入服务的 class 而无需在子 class 中复制注入器?

Extending a class that has injected services without duplicating injectors in child class?

好的,所以我正在深入研究 TypeScript 继承(特别是在 Angular 11 中),并且我已经设置了一个 BasePageComponent 来提供跨平台存在的所有必要功能和服务页。 我 运行 遇到的问题是,现在我的基础越来越臃肿,因为有些服务仅在一两个页面上使用,但为了扩展基础,我们将这些服务包含在基础中.

export class BasePageComponent {

  constructor(
    public uiPopupService: UiPopUpService,
    public loaderService: LoaderService,
    public questionService: QuestionService,
    public aBunchOfOthers: OTHERS,
    public exampleOneOffService: ExampleOneOffService
  ) {}
}

我意识到重复所有注入的服务,然后将它们全部传递到 BasePageComponent 会更高效:

export class ChildPageComponent extends BasePageComponent {

  constructor(
    public uiPopupService: UiPopUpService,
    public loaderService: LoaderService,
    public questionService: QuestionService,
    public aBunchOfOthers: OTHERS,
    private exampleOneOffService: ExampleOneOffService
  ) {
    super(uiPopupService, loaderService, questionService, aBunchOfOthers);
  }
}

如果没有其他办法,我会做上面的事情,但是我已经在示例代码中暗示了,我有一堆包含在基础中的其他微服务(比如 15-20),所以我希望能够做这样的事情,我只声明一个额外的服务,并且仍然从父 class 继承所有其他服务,但我没有找到这样做的方法。

export class ChildPageComponent extends BasePageComponent {

  constructor(private otherExampleService: OtherExampleService){
    super() 
  };
}

这种模式是否存在,我只是没有用谷歌搜索正确的关键字?

这不是 DI 的工作方式。

DI会提供给你构造函数的参数。它不知道父 class.

如果从子 class 调用父 classes,则不会从 DI 获得任何信息。在这种情况下,参数通过 super()

传递

这有点讽刺,您使用继承来避免依赖注入,而实际上您应该使用依赖注入来避免继承。如果组件有共享服务,你需要做的就是把你需要的那些放在构造函数中就大功告成了。

如果它们有共享功能,您可以将这些功能放在一个服务中。如果它们有共享变量,您可以使用服务来传递数据。重点是让组件作为它们自己独立的实体,所以如果你改变一个,它不会影响任何其他人。

服务遵循同样的理念,因为您可以更改服务的实现,而不必触及任何使用该服务的文件。想想你的设计,如果你需要删除或添加服务到基础组件会发生什么?您现在需要去编辑整个项目中的所有其他组件。当您将服务注入组件时,它也会创建该服务的 实例 。通过将所有 服务注入每个 组件,您正在创建无数浪费内存和处理能力的实例。你真的在 return 中得到了什么吗?

我想说的是你应该尽量避免扩展组件。 Angular 提供了更好的设计理念。

要回答您的问题,是的,您可以创建一个导入所有其他服务的全局服务,然后注入该大型服务。然后您可以扩展该服务并导入更多内容。但是为了所有神圣的爱,请不要。

感谢 for his link to another answer ( )。

我能够将 Injector.get 用于基本上在每个子组件中使用的 15 个小型服务。然后对于较大的服务和只在少数子组件上使用的服务,我将它们注入到相关组件中。

对于以后来到这里的任何其他人:我 运行 遇到的一个障碍是 Angular 的 ActivatedRoute 显然不适用于 Injector.get (参见 ),所以我不得不将其注入到每个相关组件中,这是其中的大部分,但这仍然比在每个页面上初始化 16 个一次性服务要好。