私は Unity IOC コンテナーを使用していますが、複数のクラスのコンテナーにアクセスするための最良の方法は何だろうと思っています。
すべてのクラスに IUnityContainer メンバーがあり、コンテナーをコンストラクターで渡す必要がありますか? IOC コンテナーを持つシングルトン クラスが必要ですか?
asp.netの開発はどうですか?
誰かが私を正しい方向に導くことができますか? ありがとう。
私は Unity IOC コンテナーを使用していますが、複数のクラスのコンテナーにアクセスするための最良の方法は何だろうと思っています。
すべてのクラスに IUnityContainer メンバーがあり、コンテナーをコンストラクターで渡す必要がありますか? IOC コンテナーを持つシングルトン クラスが必要ですか?
asp.netの開発はどうですか?
誰かが私を正しい方向に導くことができますか? ありがとう。
私見では、コンテナー全体をクラスに挿入したり、アプリケーション全体の静的 IoC サービス ロケーターを使用したりすることはお勧めできません。
クラスのコンストラクター (Foo と呼びましょう) から、作業を完了するためにどのような種類のサービス/オブジェクトを使用しているかを確認できるようにしたいと考えています。これにより、明確性、テスト容易性、およびデガバビリティが向上します。
Foo がメール サービスのみを必要としているとしますが、コンテナー全体を渡し、コードのどこかでメール サービスがコンテナーから解決されるとします。この場合、フォローするのは非常に困難です。代わりに、電子メール サービスを直接注入して、Foo の依存関係をより明確に示す方が適切です。
Foo がメール サービスの複数のインスタンスを作成する必要がある場合は、(IoC コンテナーを介して) EmailServiceFactory を作成して注入することをお勧めします。これにより、必要なインスタンスがその場で作成されます。
後者の場合、Foo の依存関係は、EmailServiceFactory が作成できるもののみ、可能な限り具体的に示されます。コンテナー全体を注入した場合、それによって提供されるサービスが Foo の正確な依存関係であるかどうかが明確ではありません。
ここで、後でメール サービスの別のインスタンスを提供する必要が生じた場合は、EmailServiceFactory 内でそれを交換します。ファクトリが作成するすべてのサービスを交換する必要がある場合 (テスト中など)、ファクトリ全体を交換することもできます。
そのため、追加のクラス (ファクトリ) を 1 つ作成する代わりに、よりクリーンなコードが得られ、グローバルな静的変数を使用するときに発生する可能性のある奇妙なバグについて心配する必要がなくなります。さらに、テスト用にモックを提供するときは、必要なモックを正確に把握しており、コンテナーの型全体をモックアウトする必要はありません。
このアプローチには、モジュールが初期化される (Prism / Modularity にのみ適用される) ときに、提供するオブジェクトのすべてのタイプを IoC コンテナーに登録する必要がないという利点もあります。代わりに、それらのオブジェクトを提供する ServiceFactory を登録するだけです。
明確にするために、モジュールの初期化クラス (IModule を実装する) は、他のモジュールによって消費されるサービスを提供するために、コンストラクターでアプリケーション全体の IoC コンテナーを受け取る必要がありますが、コンテナーはモジュールのクラスに侵入してはなりません。
最後に、ここにあるのは、追加の間接化レイヤーが問題を解決する方法のもう 1 つの良い例です。
IOCコンテナをプロセスの最高レベル/エントリポイントに配置し、それを使用して、その下にあるすべてのものに依存性を注入します。
次のように、コンテナー自体を登録して、他のすべての依存関係プロパティと同様に注入することができます。
IUnityContainer container = new UnityContainer();
container.RegisterInstance<IUnityContainer>(container);
それにアクセスする必要があるクラスには、次のプロパティがあります。
private IUnityContainer unityContainer;
[Dependency]
public IUnityContainer UnityContainer
{
get { return unityContainer; }
set { unityContainer = value; }
}
したがって、そのようなクラスのインスタンスが解決/構築されるたびに、コンテナが注入されます。
これは、シングルトン パターンでは不可能な、同じアプリケーション内の複数のコンテナーで機能するため、より柔軟です。
すべてのオブジェクトがコンテナへの参照を必要とする場合は、コードをいくつか作り直す必要があります。どこでも new を呼び出すよりは望ましいことですが、コード全体にオブジェクト グラフを作成する責任が分散されます。このような使用方法では、IoC コンテナーではなく ServiceLocator のように使用されているように感じます。
別のオプションはCommonServiceLocatorを使用することです。これは無意味な間接的かもしれませんが、ServiceLocator.Current
すべてのクラスで知られているインスタンスとしてを使用できます
私のブログにこのテーマに関する投稿があり、t3mujin の回答に沿ったものを使用しています。自由に使用してください (SharePoint に関連していることを気にしないでください...それは問題ではありません):
http://johanleino.spaces.live.com/blog/cns!6BE273C70C45B5D1!213.entry