Angular2 DI:如何在@NgModule下注入依赖?

for*_*d04 5 dependency-injection typescript angular2-di angular

TL; DR 25.10.16:更新

我重新命名标题以提供更多说明,因为我仍然关注正确的解决方案.

给定一个模块

@NgModule({
  imports: [
    ExternalModule.forRoot(config),
  ],
  providers: [EXTERNAL_PROVIDERS(config)],
})
export class MyModule{}
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:有没有可能我可以像这样通过我传递的配置注入依赖?

  1. ExternalModule.forRoot(@Inject(MyConfig) config : MyConfig)
  2. providers: [EXTERNAL_PROVIDERS(@Inject(MyConfig) config)] (

我不想{provide: xxx, deps :[xxx], useFactory : xxx}为每个给定的外部提供商创建.

我试图初始化Application Wide Service Locator与访问所描述的根注射器在这里,但角度2.1.0 ngDoBootstrap不能按预期工作.

----------

旧帖子:

我想知道在Angular2中配置外部第三方库提供程序的正确模式是什么.

我们举一个例子(Typescript中的代码示例):

有一个库公开其提供者,并通过config对象文字提供一些配置选项:

export function THIRD_PARTY_PROVIDERS(config = {}): Provider[] {
  return [
    {
      provide: ExtConfigurableService,
      deps: [Http],
      useFactory: (http: Http) => {
        return new ExtConfigurableService(http, config);
      }
    },
    ExtOtherService
  ];
}
Run Code Online (Sandbox Code Playgroud)

然后在客户端,这些提供商可以包含在@NgModule:

@NgModule({
  providers: [
    THIRD_PARTY_PROVIDERS({foo : 'bar'})
  ],
})
export class ClientModule { }
Run Code Online (Sandbox Code Playgroud)

但是如果我的配置对象本身依赖于现有的服务MyService呢?我不能在providers数组中注入依赖项.从我的观点来看,唯一的方法是使用FactoryProvider:

const myConfigProvider = {
    provide: MyConfig,
    deps: [MyService],
    useFactory: (MyService) => {
      return new MyConfig(MyService);
    }
  };
Run Code Online (Sandbox Code Playgroud)

鉴于此,我怎么能注入MyConfigTHIRD_PARTY_PROVIDERS


我提出的唯一解决方案并不令人满意:

  1. 使用OpaqueToken此处第三方提供商端导出的(Angular 2路由器)
  2. 从客户端配置所有提供程序手动

第一个只能从第三方提供者完成:导出令牌并要求该令牌作为工厂提供者中的自己的依赖.

第二个是非常难看的,因为你必须自己知道并配置第三方lib的实现细节/服务.

@NgModule({
      providers: [
        {provide: ExtConfigurableService, deps: [MyConfig], useFactory: ...},
        ExtOtherService
      ],
    })
    export class ClientModule { }
Run Code Online (Sandbox Code Playgroud)

角度2(客户端和第三方提供商端)的首选模式是什么?


更新19.10.16

我实施了我的第一个解决方案提案,它运行正常.但它要求您可以控制外部库/同意项目所有者的更改或分叉回购.

第三方lib.ts:

   export const JWT_CONFIGURATION = new OpaqueToken('THIRD_PARTY_PROVIDER_TOKEN');
    ...

    @Injectable()
    export class ExtConfigurableService {

      constructor(@Inject(JWT_CONFIGURATION) config: any) {
        // do someting with client provided config 
      }
Run Code Online (Sandbox Code Playgroud)

我-module.ts

 @NgModule({
      providers: [
        {
        provide: JWT_CONFIGURATION,
        deps: [MyService],
        useFactory: (mySvc: MyService) => {
          return {foo : 'bar'};
        }, THIRD_PARTY_PROVIDERS
      ]
    })
    export class MyModule { }
Run Code Online (Sandbox Code Playgroud)

但是如果外部lib要求你将配置作为参数传递(如在顶部的示例中),我仍然不知道如何将myconfig注入其中.

@Inject()除了构造函数或工厂提供者之外,还有Angular 2其他注入依赖关系的方法吗?