制御の反転 (IoC) は、初めて遭遇したときには非常に混乱を招く可能性があります。
- それは何ですか?
- それはどんな問題を解決しますか?
- いつ使用するのが適切で、いつ使用しない方が良いのでしょうか?
ベストアンサー1
Inversion-of-Control
(IoC)パターンは、自分自身で直接操作するのではなく (つまり、制御を反転したり、外部のハンドラー/コントローラーにリダイレクトしたりするのではなく)、反応を「実装」および/または制御するあらゆる種類の を提供することです。( DI )パターンは、IoC パターンのより具体的なバージョンであり、コードから依存関係を削除することがすべてです。callback
Dependency-Injection
すべての
DI
実装は とみなすことができますIoC
が、 と呼ぶべきではありませんIoC
。依存性注入の実装はコールバックよりも難しいからです (代わりに一般的な用語「IoC」を使用して製品の価値を下げないでください)。
DI の例として、アプリケーションにテキスト エディター コンポーネントがあり、スペル チェックを提供したいとします。標準コードは次のようになります。
public class TextEditor {
private SpellChecker checker;
public TextEditor() {
this.checker = new SpellChecker();
}
}
ここで行ったことは、 とTextEditor
の間に依存関係を作成しますSpellChecker
。IoC シナリオでは、代わりに次の操作を行います。
public class TextEditor {
private IocSpellChecker checker;
public TextEditor(IocSpellChecker checker) {
this.checker = checker;
}
}
最初のコード例では、SpellChecker
( this.checker = new SpellChecker();
) をインスタンス化しています。つまり、TextEditor
クラスは クラスに直接依存していますSpellChecker
。
2 番目のコード例では、SpellChecker
依存関係クラスを のTextEditor
コンストラクタ シグネチャに含めることで抽象化を作成しています (クラスで依存関係を初期化しません)。これにより、依存関係を呼び出して、次のように TextEditor クラスに渡すことができます。
SpellChecker sc = new SpellChecker(); // dependency
TextEditor textEditor = new TextEditor(sc);
依存関係を署名に挿入しているため、クラスを作成するクライアントTextEditor
はどの実装を使用するかを制御できるようになりました。SpellChecker
TextEditor
IoC が他の多くのパターンのベースであるのと同様に、上記のサンプルは多くの依存性注入の種類の 1 つにすぎないことに注意してください。次に例を示します。
- コンストラクターインジェクション。
のインスタンスは
IocSpellChecker
、自動的に、または上記と同様に手動でコンストラクターに渡されます。 - セッターインジェクション。
のインスタンスがセッター メソッドまたはプロパティ
IocSpellChecker
を介して渡される場合。public
- サービス検索および/またはサービスロケータ
TextEditor
既知のプロバイダーに、 タイプのグローバルに使用されるインスタンス (サービス) を問い合わせる場合IocSpellChecker
(おそらく、そのインスタンスを保存せずに、プロバイダーに何度も問い合わせることになります)。