2017-02-11 6 views
3

ランタイムスイッチに応じて、いくつかの角度サービスを動的に構成する必要があります。その後、私のAppModuleに私はMyModule.forRoot(myConfig)としてこれをインポートします動的モジュール/サービス構成とAOT

@NgModule({ 
    imports: [HttpModule], 
    providers: [] 
}) 
export class MyModule { 
    static forRoot(config: MyConfiguration): ModuleWithProviders { 
    return { 
     ngModule: MyModule, 
     providers: [ 
     SomeService, 
     { 
      provide: SomeOtherService, 
      useFactory: (some: SomeService, http: Http) => { 
      switch (config.type) { 
       case 'cloud': 
       return new SomeOtherService(new SomethingSpecificForCloud()); 
       case 'server': 
       return new SomeOtherService(new SomethingSpecificForServer()); 
      } 
      }, 
      deps: [SomeService, Http] 
     }, 

     ] 
    }; 
    } 
} 

:AOT前の日に、私はそれが次のコードを使用して動作するようになりました。

CLIとAngularを更新したため、静的解析ができないため、これはもはやコンパイルされません。私は理由を理解していますが、それを解決する正しい方法はまだわかりません。

私は最初にこのforRoot()アプローチを悪用しましたか?ランタイムスイッチに応じて、異なるサービスを生成するように、モジュールをどのように記述しますか?

答えて

3

私はそれを実現する1つの方法を見つけました:プロバイダー経由で構成を公開し、次に「静的な」ファクトリー関数に注入しました。上記のコードは次のようになります。

// 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. 使用角度CLI環境:

    は、私は別の解決策を見つけました。
  2. 環境ごとに異なる実装または依存関係を持つサービス用の抽象クラス/インタフェースを作成します。
  3. それぞれの環境ファイルから適切なタイプをエクスポートします(誰が普通のJSオブジェクトでなければならないと言いましたか?)。
  4. モジュールプロバイダ定義で、環境からをインポートします。
  5. コンパイル時に、CLI環境によって正しいことがリンクされます。

さらに詳しい情報とサンプルプロジェクトはmy blogです。

+0

これは唯一の選択肢だと思います。 1つの発言:v4から、あなたは 'OpaqueToken'の代わりに' InjectionToken'を使うべきです。 – mat3e

関連する問題