动态模块/服务配置和AOT

时间:2017-02-11 12:54:04

标签: angular angular2-aot

我需要动态配置一些Angular服务,具体取决于运行时开关。在AOT之前的几天,我使用以下代码开始工作:

AppModule

然后在我的MyModule.forRoot(myConfig)中,我会将其导入为forRoot()

当我更新CLI和Angular时,它不再编译,因为它无法进行静态分析。我理解为什么,但我仍然不确定解决问题的正确方法是什么。

我是否首先滥用了这种{{1}}方法?如何编写模块以便根据运行时开关生成不同的服务?

1 个答案:

答案 0 :(得分:7)

我找到了一种实现方法:通过提供程序公开配置,然后注入“静态”工厂函数。上面的代码如下所示:

// Necessary if MyConfiguration is an interface
export const MY_CONFIG = new OpaqueToken('my.config');

// Static factory function
export function someOtherServiceFactory(config: MyConfiguration,some: SomeService, http: Http) {
  switch (config.type) {
    case 'cloud':
      return new SomeOtherService(new SomethingSpecificForCloud());
    case 'server':
      return new SomeOtherService(new SomethingSpecificForServer());
  }
}

@NgModule({
  imports: [HttpModule],
  providers: []
})
export class MyModule {
  static forRoot(config: MyConfiguration): ModuleWithProviders {
    return {
      ngModule: MyModule,
      providers: [
        SomeService,
        { provide: MY_CONFIG, useValue: config },
        {
          provide: SomeOtherService,
          useFactory: someOtherServiceFactory,
          deps: [MY_CONFIG, SomeService, Http]
        },

      ]
    };
  }
}

它有效,但我仍然非常有兴趣知道这是否真的是一个好主意,或者我是在做一些非常错误的事情,应采取完全不同的方法来解决这个问题。

我找到了另一个解决方案:

  1. 使用Angular CLI环境。
  2. 为不同环境的不同实现或依赖项的服务创建抽象类/接口。
  3. 从每个enviromnent文件中导出正确的类型(谁说它只是一个普通的JS对象?)。
  4. 在模块提供程序定义中,从环境中导入
  5. 在编译时,CLI环境将使正确的事情得到链接。
  6. my blog的更多信息和示例项目。