带树抖动的动态服务注入

时间:2019-04-02 23:50:34

标签: angular dependency-injection

我正在尝试创建一个ApiService,用作Angular 7应用程序中一系列其他服务的包装。目前,我正在将服务注入到父ApiService的构造函数中:

import { Injectable, Inject } from '@angular/core';

import { StoreInfoService } from '@services/store-info/1.0/store-info.service';
import { MenuService } from '@services/menu/1.0/menu.service';

@Injectable({
  providedIn: 'root'
})
export class ApiService {
  constructor(
    @Inject(MenuService) public menu: MenuService,
    @Inject(StoreInfoService) public storeInfo: StoreInfoService,
  ) {}
}

这工作正常,并允许我通过执行以下操作来调用API端点:

api.storeInfo.get('S9293')

但是,这不允许我利用摇树的优势。我在ApiService中注入的每个服务都将包含在我的应用程序中,并且我预计ApiService中将包含大量服务,并且并非每个客户端都需要使用每个服务。

在充分利用树状摇动的情况下,有没有办法像这样在父包装器服务中包装服务?

1 个答案:

答案 0 :(得分:1)

我不认为在将服务注入API服务时可以摇晃树(但是我很容易出错)。

我读了一些书,发现了一些很棒的信息。 Here是一个链接,演示了树震动如何与新提供者一起工作。

这听起来有些怪异,但是您可以尝试的另一种方法是将file replacements与CLI一起使用,以设置实际上在模块中提供旧方法的“动态”提供程序,以及使用它们在服务上使用@Optional装饰器的位置。这是环境ts的示例:

// abstract-service.ts
@Injectable()
export abstract class AbstractService1 {
  abstract myMethod(value: number): string;
}

// service.ts
@Injectable()
export class Service1 extends AbstractService1 {
  constructor() {
    super();
  }

  myMethod(value: number) {
    ..// do stuff
    return '';
  }
}

// env ts
export const environment = {
  ..
  specialProviders: [
    // no provider and having the AbstractService1 optional only has a reference to the method, no meat!
    { provide: AbstractService1, useClass: Service1 }
  ],
  ..


// angular json
"fileReplacements": [
  ..
  {
    "replace": "src/environments/environment.ts",
    "with": "src/environments/environment.<my-env>.ts"
  }
  ..
],


// shared service ts
..
constructor(
  @Optional() public Service1: AbstractService1,
  @Optional() public Service2: MyService2,
) {}
..


// module
providers: [
  ..
  ...environment.specialProviders,
  ..
],

(编辑)添加了针对“可选”服务的抽象类的演示,因此,如果未提供该类的内容,则不会包含在构建中。在使用方法的地方仍然会有方法引用。