web-dev-qa-db-ja.com

依存性注入(DI)と制御の反転(IOC)の違い

Dependency Injection(DI)とInversion Of Control(IOC)のリファレンスをたくさん見てきましたが、それらに違いがあるかどうかは本当にわかりません。

どちらか一方または両方を使い始めたいのですが、それらの違いについて少し混乱しています。

119
Elijah Manor

定義

制御の反転は、アプリケーションフレームワークコードからの具体的な実装の認識を減らし、アプリケーションのドメイン固有のコンポーネントをさらに制御できるようにすることを目的とした設計パラダイムです。従来のトップダウン設計されたシステムでは、アプリケーションの論理フローと依存関係認識は、最初に設計されたコンポーネントから最後に設計されたコンポーネントへと流れます。そのため、コントロールの反転は、アプリケーションのコントロールと依存関係の認識をほぼ文字通り反転したものです。

依存性注入は、コンパイル時に他のクラスが依存するクラスのインスタンスを作成するために使用されるパターンであり、コンパイル時にどの実装を使用してその機能を提供するかがわかりません。

一緒に働く

特定の機能を提供するコンポーネントを作成するためのメカニズムが必要なため、制御の反転は依存関係注入を利用できます。他のオプションが存在し、使用されています。アクティベータ、ファクトリメソッドなどですが、フレームワーククラスが代わりに必要な依存関係を受け入れることができる場合、フレームワークはそれらのユーティリティクラスを参照する必要はありません。

作業中のこれらの概念の1つの例は、 Reflector のプラグインフレームワークです。コンパイル時にアプリケーションがプラグインについて何も知らなかったとしても、プラグインはシステムをかなり制御します。これらの各プラグインで単一のメソッドが呼び出され、メモリが機能する場合は初期化し、プラグインに制御を渡します。フレームワークは彼らが何をするかを知りません、ただ彼らにそれをさせるだけです。コントロールはメインアプリケーションから取得され、特定の作業を行うコンポーネントに与えられます。制御の反転。

アプリケーションフレームワークにより、さまざまなサービスプロバイダーを介してその機能にアクセスできます。プラグインには、作成時にサービスプロバイダーへの参照が与えられます。これらの依存関係により、プラグインは独自のメニュー項目を追加したり、ファイルの表示方法を変更したり、適切なパネルに独自の情報を表示したりすることができます。依存関係はインターフェースによって渡されるため、実装が変更される可能性があります。契約がそのまま残っている限り、コード。

当時、構成情報、リフレクション、およびアクティベーターオブジェクト(少なくとも.NET)を使用してプラグインを作成するために、ファクトリメソッドが使用されていました。今日、ツールがあります [〜#〜] mef [〜#〜] 1つで、アプリケーションフレームワークがリストを受け入れる機能など、依存関係を注入するときに幅広いオプションを使用できます依存関係としてのプラグイン。

まとめ

これらの概念を使用して個別にメリットを提供することができますが、これらの概念を組み合わせることにより、はるかに柔軟で再利用可能でテスト可能なコードを作成できます。そのため、これらはオブジェクト指向ソリューションを設計する上で重要な概念です。

53
Chuck

わかりやすい記事IOC and DIhttp://martinfowler.com/articles/injection。 html

IOC(制御の反転)

IOCとは

  1. インターフェイスへのコーディング(1つのコンポーネントは、実装ではなく他のコンポーネントのインターフェイスに依存する必要があります)、および

    interface iComp_2 {...}
    
    class Comp_1 {
        iComp_2 c2 = ….;
    }
    
  2. コンポーネント実装固有のコード(例:

    Comp_1 {
        iComp_2 c2 = getComp_2_Impl(); // not new Comp_2_Impl();
    }
    

IOCは、次のいずれかによって達成できます。

1。 DI(依存性注入)

3 types of DI

1.1 Constructor Injection

1.2 Setter Injection

1.3 Interface Injection

2。サービスロケーター

DI(依存性注入)コンテナ

コンパイル時ではなく実行時の実装の決定:いくつかの構成ファイルに基づいて、使用するインターフェイスの具体的な実装を実行時に決定します(したがって、コンパイル時に使用する実装がわからないため、アプリケーションの構成可能性が向上します)。 。異なるモジュール間の具体的な関係が「実行時」に決定される実装です。

依存関係注入後のimplのインスタンス化:implを決定した後、最初にすべての依存関係(構成ファイルで指定)を作成し、次にそれらの依存関係をそのimplに注入することにより、そのimplをインスタンス化します

インスタンスのライフサイクル管理:DIコンテナーは通常、ライフサイクルの管理に必要なオブジェクト、またはシングルトンやフライウェイトなどの将来の注入に再利用されるオブジェクトへの参照のみを保持します。コンテナーへの呼び出しごとにいくつかのコンポーネントの新しいインスタンスを作成するように構成されている場合、コンテナーは通常、作成されたオブジェクトを忘れます。そうしないと、ガベージコレクターは、使用されなくなったときにこれらのオブジェクトをすべて収集するのに苦労します。

0
Yatendra Goel