Angular 5 次服务 replacement/override

Angular 5 service replacement/override

我为我的项目创建了一个包含一些组件和服务的核心库。我用 ng-packagr 构建了这个库。在引用库的消费项目中,我构建了包含库提供的组件的 webapp。到目前为止没有什么特别的。但有时我想要一个组件(来自我的库)从库外的服务调用一个方法。这可能吗?我能以某种方式向库中定义的组件注入服务吗?

干杯

我以前用这样的东西实现过这个:

您的图书馆的服务应该被定义为一个接口而不是一个具体的实现(就像在 OO 语言中经常做的那样)。如果您的实施应用程序有时只想传递自己的服务版本,那么您应该在您的库中创建一个默认服务,并按原样使用它:

import { Component, NgModule, ModuleWithProviders, Type, InjectionToken, Inject, Injectable } from '@angular/core';

export interface ILibService {
  aFunction(): string;
}

export const LIB_SERVICE = new InjectionToken<ILibService>('LIB_SERVICE');

export interface MyLibConfig {
  myService: Type<ILibService>;
}

@Injectable()
export class DefaultLibService implements ILibService {
  aFunction() {
    return 'default';
  }
}

@Component({
  // whatever
})
export class MyLibComponent {
  constructor(@Inject(LIB_SERVICE) libService: ILibService) {
    console.log(libService.aFunction());
  }
}

@NgModule({
  declarations: [MyLibComponent],
  exports: [MyLibComponent]
})
export class LibModule {
  static forRoot(config?: MyLibConfig): ModuleWithProviders {
    return {
      ngModule: LibModule,
      providers: [
        { provide: LIB_SERVICE, useClass: config && config.myService || DefaultLibService }
      ]
    };
  }
}

然后在您的实施应用程序中,您可以通过库的 forRoot 方法传入可选配置(​​请注意,每个应用程序仅应调用一次 forRoot 并且尽可能在最高级别调用).请注意,我已将 config 参数标记为可选,因此即使您没有要传递的配置,也应该调用 forRoot

import { NgModule, Injectable } from '@angular/core';
import { LibModule, ILibService } from 'my-lib';

@Injectable()
export class OverridingService implements ILibService {
  aFunction() {
    return 'overridden!';
  }
}

@NgModule({
  imports: [LibModule.forRoot({ myService: OverridingService })]
})
export class ImplementingModule {

}

这是我记忆中的,因为我目前手头没有代码,所以如果它出于任何原因不起作用,请告诉我。