私は、制御の逆転と、これに関する注意事項と理解事項を理解しようとしています。私が読んだすべての記事の中に、サービス・ロケーター・パターンを使用しないことを強く要求するMark Seemann(SOで広くリンクされている)による one があります。
その後、途中でどこかに出くわしました この記事 ケンが私たち自身のIoCを構築するのを手伝ってくれました。
これはサービスロケータパターンの実装にすぎないことに気付きました。
質問:
回答の統合:
回答1. Kelly :サービスロケーターパターンは、最初のResolve呼び出しで実際に使用されます。サービスロケータパターンは、少なくとも1回使用する必要があります。
回答2 Eric :Ioc.Resolve(ISomeInterface)を呼び出すだけでは、IoCコンテナーがサービスロケーターとして使用されているという意味ではありません。結局のところ、Resolve()はどこかで呼び出される必要がありますよね?
回答3. Tungano :いいえ、彼のコードには依存関係を受け取るコンストラクターが含まれています...いいえ、コンテナーはパターンを「使用」していません。コンテナーを使用してパターンを使用するかどうかは、プログラマ次第です。それはあなたがそれを一緒に配線する方法にすべてあります。基本的に、DIとService locatorの両方のコンテナーを使用できます。
回答4. Gnat :...工場とルックアップ... [コントロールの反転に使用できます。]
上記の回答のおかげで、IoC自体がService Locatorパターンを使用していることがわかりました。これは本質的に有害ではありません。 IoCの使用は、さまざまな方法で実行できます(Service Locatorパターンを含む)。これは、依存関係を注入する他のオプションを使用して注意する必要がある部分です。
Ioc.Resolve(ISomeInterface)
を呼び出すだけでは、IoCコンテナがサービスロケータとして使用されているわけではありません。結局のところ、Resolve()
はどこかと呼ばれる必要がありますよね?
手がかりはwhereおよび何回 is IoC.Resolve()
が呼び出されていますか?それが依存オブジェクト自体の至る所で呼び出されている場合は、IoCコンテナーがサービスロケーターとして誤用されていることを示しています。 Resolve()
が1つの中心的な場所(通常は「コンポジションルート」と呼ばれます)で呼び出されている場合、おそらく正しく使用されています。
あなたが言及した記事は、いつ、どこでResolve()
を呼び出すかについて話しておらず、それが呼び出された後に何が起こるかを説明しているだけです。
1)いいえ、彼のコードには依存関係を受け取るコンストラクターが含まれています。
public BuildDirectoryStructureService(IFileSystemAdapter fileSystemAdapter)
IoCコンテナーが依存関係を注入しています。
サービスロケータを使用した場合、BuildDirectoryStructureServiceは依存関係を自分で取得します。例えば:
public BuildDirectoryStructureService()
{
this.fileSystemAdapter = Locator.Current.Resolve<IFileSystemAdapter>();
}
IoCコンテナーをサービスロケーターとして使用できます。
2&3)
いいえ、コンテナはパターンを「使用」しません。コンテナーを使用してパターンを使用するかどうかは、プログラマ次第です。それはあなたがそれを一緒に配線する方法にすべてあります。
基本的に、DIとService locatorの両方のコンテナーを使用できます。
4)コンストラクターインジェクションを実行できますが、実際には制御の反転はありません。コンストラクターで具象型を要求できます。あなたが注入する依存関係は、複数の実装などのための実用的な抽象化を持っていないかもしれません。
制御の逆転は ハリウッドの原則 に合わせて行われます。私たちに電話しないでください。サービスを操作する代わりに、サービスが定義するインターフェースを介してサービスを「コールバック」します。