2016-12-19 3 views
4

角度2 - バックグラウンドサービス

我々はAngular2アプリを構築している、と一つのモジュールに関連する特定のサービスの多くを蓄積しているのインスタンスを生成します。これらのサービスはすべて、アプリ内のイベントシステムSubject<Type>に緩く結合されています。

これらのサービスは直接参照されることはありませんのでコンストラクタ

を経由してインスタンス化、およびイベントのみに加入し、私たちは何とかそれをインスタンス化する必要があります。現在は、それらを使用される別のサービスのコンストラクタに挿入します。

// Services not used, just to make sure they're instantiated 
constructor(
    private appService1: AppService1,  
    private appService2: AppService2, 
    private appService3: AppService3, 
    ... 
){ } 

これはハックのビットのように思える、明示的にコンストラクタを介してそれらを注入せずにインスタンス化する必要があるサービスを述べるためのより良い方法はありますか?

+1

なぜあなたはそれらを単に「新しくできませんか? –

+0

ああ、これは恥ずかしいほど明らかです。乾杯 –

答えて

2

様々なコメントで述べたように、一つの選択肢は、直接このようなサービスをインスタンス化するだけで、これは

// app.module.ts 

@NgModule({ 
    providers: [ 
    { provide: AppService1, useValue: new AppService1() }, 
    { provide: AppService2, useValue: new AppService2() }, 
    { provide: AppService2, useValue: new AppService3() } 
    ] 
}) export class AppModule {} 

ようになり、それががによって処理されすべてに反するので、あなたは直接インスタンス化を避けるために誘惑されるかもしれませんInjectorの考え方ですが、いくつかの理由でDIやテスト容易性が損なわれることはありません。

1つの理由は、構成可能なローダーの使用と組み合わせたESモジュールの使用、およびTypeScriptの構造型の表現の表現性によって、実行時に実行時にこれらの種類の依存性をスワップすることができます。 SystemJSのようなローダー。

非常にの場合は、アプリの構造を再評価する必要がありますが、一般的にこのソリューションが最も簡単なユースケースがたくさんあります。 また、インジェクタのサイクルを壊す可能性があります。

インジェクタのブレークサイクルでは、別のサービスのコンストラクタに注入する必要がある必要なサービスのインスタンスを、useValueで指定された式の値を参照するだけで取得できることを意味します。この手法は、useFactoryでさらに便利です。それにかかわらず、これはかなり一般的ではありませんが、有効な回避策になる可能性があります。

+0

ありがとうございます、これは私が探しているようですが、インジェクタのブレークサイクルはどういう意味ですか? –

+0

'AppService1'が別のサービスを使用するとどうなりますか?例えば、それが他のサービスによって提供される観察可能なものに加入しているとき。 'useValue'プロパティ式で別のサービスのインスタンスを参照するにはどうすればいいですか? – Readren

+0

サービスに依存関係がある場合は、別のパターンを使用する必要があります。 –

1

サービスは、提供する際にインスタンス化されます。

コンストラクタで何をしているのかは、既存のサービスインスタンスをクラスに注入して使用できるようにすることです。

一つは、アプリモジュールである:

は、インスタンスまたはサービスを提供するための3つの方法があります。

@NgModule ({ 
    providers: [ myservice1, myservice2], 
}) 

これはサービスをインスタンス化し、アプリケーション全体で利用可能にします。

また、フィーチャーモジュールまたは共有モジュールで提供することもできます。これは同じことを実現します。アプリケーションモジュールで提供する場合は、遅延ロードされているフィーチャモジュールに同じサービスを提供し、グローバルに利用できる2番目のインスタンスをインスタンス化します。最初のものはエーテルに消えます。

特定のコンポーネントのサービスをインスタンス化し、各コンポーネントごとに複数のインスタンス化を設定する場合は、そのコンポーネントのメタデータにサービスを提供します。

@Component ({ 
    providers: [myservice] 
}) 

次に、コンストラクタを使用して注入します。

+0

これはあまり単純化されていません。また、インスタンス化することで、サービスがインスタンス化される最も明白な方法を省略しました。 –

+1

それをアプリケーションの任意の部分のプロバイダにリストすると、サービスをインスタンス化するようには見えませんが、私が知る限り、サービスはコンストラクタを介して注入する必要があります。 –

+1

インスタンス化されるかどうかを確認する方法の1つは、プロバイダ提供することです。[{provide:AppService、useValue:new AppService()}] ' –