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

时间:2016-10-18 11:13:03

标签: angular typescript dependency-injection angular2-di

TL; DR 25.10.16:更新

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

给定一个模块

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

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

  1. ExternalModule.forRoot(@Inject(MyConfig) config : MyConfig)
  2. providers: [EXTERNAL_PROVIDERS(@Inject(MyConfig) config)]
  3. 我不想为每个给定的外部提供商创建{provide: xxx, deps :[xxx], useFactory : xxx}

    我尝试按照here所述初始化Application Wide Service Locator访问根注入器,但使用Angular 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
      ];
    }
    

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

    @NgModule({
      providers: [
        THIRD_PARTY_PROVIDERS({foo : 'bar'})
      ],
    })
    export class ClientModule { }
    

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

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

    鉴于此,我如何将MyConfig注入THIRD_PARTY_PROVIDERS

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

    1. 使用第三方提供商方面的导出OpaqueToken,例如here (Angular 2 Router)
    2. 从客户端配置所有提供商手动
    3. 第一个只能从第三方提供商处完成:导出令牌并在工厂提供商中要求该令牌作为自己的依赖。

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

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

      角度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 
            }
      

      MY-module.ts

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

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

      除了构造函数或工厂提供程序之外,Angular 2还有其他方法可以使用@Inject()注入依赖项吗?

0 个答案:

没有答案