2016-12-11 3 views
1

ドキュメントがAngular2 Dependency Injection - 理にかなっているか、それとも強化されていますか?

依存性の注入は

コードの依存関係を管理するための強力なパターンですが、角度のDIはどんな意味があるのでしょうか?言うように

HeroComponentがHeroModuleにあり、HeroServiceが使用されているとします。 HeroComponentでそれを使用するに 我々はする必要があります:モジュールプロバイダーでHeroModuleで

  1. インポートHeroService
  2. を注入HeroService
  3. HeroComponent
  4. でインポートHeroService
  5. タイプを追加またはコンポーネントのパラメータに注入されたサービスを追加します。

なぜHeroComponentにだけではなく、

  1. 輸入HeroServiceしていますか?

私たちのアプリを介してまだシングルトンを持つことができるようにインスタンスをエクスポートすることができます。テスト中に実際の実装ではなくモックをインポートできるようにwebpack/karmaを設定できます。

誰かがAngularのDIを使ってアーキテクチャの密接な結びつきをなくすことができますが、それは本当ですか? Angular 1.xでは、実際にコンストラクタでparamsを指定しました。しかし、Angular2では、依存関係をさらにインポートする必要があり、どこから指定する必要があります。だから、これは疎結合はどこですか?

例:

import { Http } from 'angular2/http'; 

export class Login { 
    constructor(http: Http) { 
    http.whatever() 
    } 
} 

たちの注入を実行することができるように、我々はそれをインポートする必要があります。そして、私たちがインポートするとき、私たちは使用するサービスを正確に定義します。上記の例と下の例との違いはありません。

import { http } from 'angular2/http'; (instance) 

export class Login { 
    constructor() { 
    http.whatever() 
    }} 
+1

これはAngular2が発明したものではありません。これは普及しているパターンであり、良い習慣と考えられています.https://en.wikipedia.org/wiki/Inversion_of_control。 http://stackoverflow.com/questions/3058/what-is-inversion-of-control、http://martinfowler.com/articles/injection.html –

+0

もちろん、IoCは普及しているパターンであり、優れたプラクティスですソリッドの原則ただし、依存関係を手動でインポートする必要がある場合は、私にとっては不可能です。 –

+0

TSにはDI用インターフェイスを使用できないが、引き続き(抽象)基本クラス(Angular2の制限ではなくTS制限)を使用できるという制限がいくつかあります。私はそれ以外の点ではIoCの話題にはまったく関連していないと思います。何らかの理由でソースコード内の型を使用したい場合は、DIに関連しない型をインポートする必要があります。 –

答えて

1

依存性注入はインポートについてではありません。それはあなたのコンポーネントの外であなたのためにインスタンスを作成することです。 DIがなければ、あなたのHeroComponentはまだHeroServiceのインポート文を追加する必要がありますし、手動HeroComponent内でそれをインスタンス化する必要があるだろう:

myHeroService: HeroService = new HeroService(); 

今、あなたは、次の3つのコンポーネントでこのサービスを使用する必要があります想像。次に、上記の行を3つの異なる場所に書く必要があります。

実際のものがまだ準備ができていない(または単体テストのモックサービスを受けたい)ので模擬サービスを使用する必要がある場合はどうすればよいですか? 3つの成分のそれぞれは、例えば、あなたは上記のシナリオに変更したことはありませんでした同じコンストラクタを持っているでしょうDIで

myHeroService: MockHeroService = new MockHeroService(); 

:DIがなければ、あなたはこのようなものには3つのコンポーネントでコードを変更する必要があるだろう:

class HeroComponent{ 

    constructor(heroService: HeroService){} 
} 

MockHeroServiceへの切り替えは、HeroModule宣言における唯一の変化(プロバイダ)が必要となる。

@NgModule({ 
... 
providers:[provide: HeroService, useClass: MockHeroService] 
}) 

上記のコードは、モジュール全体のシングルトンを作成する角度指示するであろう(アプリ) 。あなたはHeroServiceの複数のインスタンスを導入することを決定した場合、その後だけでproviders:[HeroService]を宣言し、(たとえばHeroComponent1HeroServiceを使用し、HeroComponent2MockHeroServiceを使用しています)HeroComponent1

@Component({ 
... 
providers:[HeroService] 
}) 

今角度が全体のアプリをMockHeroServiceインスタンスを作成し、 HeroComponent1とその子のHeroServiceの別のインスタンスです。

このサービスを使用するコンポーネントでコンストラクタのシグネチャを変更する必要はありません。

ここで、あるコンポーネントで、HeroServiceまたはMockHeroServiceのいずれかを条件付きでインスタンス化するファクトリ関数を導入すると決めたとします。 useFactory構文を使用して、そのようなコンポーネントのプロバイダを宣言するだけです。

私は続けることができます:)

+0

しかし、HeroComponentに 'constructor(heroService:HeroService){}'を追加する場合は、上記のHeroServiceもインポートする必要があります。それ以外の場合、コンパイラはHeroServiceが何であるかを知りません。したがって、特定のサービスを指す必要があります。 –

+0

特定のサービスを指していません。プロバイダを検索するためのキーとして使用される型を指します。実際に注入されたサービスは、答えに表示される 'MockHeroService'のように' HeroService'のサブクラスになることができます。 –

関連する問題