依存性注入の実装について、ある具体的な例では混乱しています。DIコンテナを介して注入される抽象ファクトリでの作業
たとえば、IClassX型の依存関係を持つSomeClassクラスがあるとします。 IClassXインターフェースの具体的な実装の
public class SomeClass
{
public SomeClass(IClassX dependency){...}
}
作成は、私がどのような実装を知らないので、私は、(Unityが使用されている)DIコンテナを設定することはできません特定のコンストラクタで、ランタイム・パラメータN
に依存しますIClassXは実行時に使用されます。 彼の本「依存性注入」のMark Seemannは、注入パラメータとして抽象ファクトリを使用すべきであることを示唆しています。
ランタイムパラメータのrunTimeParamに基づいてIClassXの実装を返すSomeAbstractFactoryがあります。
public class SomeAbstractFactory
{
public SomeAbstractFactory(){ }
public IClassX GetStrategyFor(int runTimeParam)
{
switch(runTimeParam)
{
case 1: return new ClassX1();
case 2: return new ClassX2();
default : return new ClassDefault();
}
}
}
工assは今噴射パラメータとしてISomeAbstractFactoryを受け入れる:
public class SomeClass
{
public SomeClass(ISomeAbstractFactory someAbstractfactory){...}
}
そして、それは大丈夫です。オブジェクトグラフを作成するコンポジションルートは1つだけです。 SomeClassにSomeAbstractFactoryを注入するようにUnityコンテナを設定します。
しかし、のは、クラスClassX1とClassX2は独自の依存関係を持っていると仮定しましょう:
public class ClassX1 : IClassX
{
public ClassX1(IClassA, IClassB) {...}
}
public class ClassX2 : IClassX
{
public ClassX2(IClassA, IClassC, IClassD) {...}
}
IClassA、IClassB、IClassCとIClassD依存関係を解決する方法は?
1. SomeAbstractFactoryコンストラクタを通して注入
私たちは、このようSomeAbstractFactoryするIClassA、IClassB、IClassCとIClassDの具体的な実装を注入することができます
public class SomeAbstractFactory
{
public SomeAbstractFactory(IClassA classA, IClassB classB, IClassC classC, IClassD classD)
{...}
...
}
ユニティ・コンテナは、最初に使用されますコンストラクタルートを作成し、貧しい人のDIを使用して、パラメータrunTimeParamに基づいて具象ClassX1またはClassX2を返す。
public class SomeAbstractFactory
{
public SomeAbstractFactory(IClassA classA, IClassB classB, IClassC classC, IClassD classD){...}
public IClassX GetStrategyFor(int runTimeParam)
{
switch(runTimeParam)
{
case 1: return new ClassX1(classA, classB);
case 2: return new ClassX2(classA, classC, classD);
default : return new ClassDefault();
}
}
}
このアプローチの
問題:
- SomeAbstractFactoryは実際にそれに属し `tの依存関係について知っています。
- オブジェクトグラフは、DIコンテナは、依存関係を解決するために使用されないであろうSomeAbstractFactoryコンストラクタとクラスの実装
- 両方を変更するために必要となる、貧しいman`s DIは、DIに
2.明示的なコールを使用しなければならない深いですコンテナ
「new up up」ClassX1またはClassX2の代わりに、DIコンテナを使用して解決します。このアプローチ
public class SomeAbstractFactory
{
public SomeAbstractFactory(IUnityContainer container){...}
public IClassX GetStrategyFor(int runTimeParam)
{
switch(runTimeParam)
{
case 1: return container.Resolve<IClassX>("x1");
case 2: return container.Resolve<IClassX>("x2");
default : return container.Resolve<IClassX>("xdefault");
}
}
}
問題:
- DIコンテナがDIの解決法のみ合成ルート(のServiceLocatorアンチパターン)で使用されていないSomeAbstractFactory
- に渡され
さらに適切なアプローチがありますか?