次のクラス階層が与えられた場合
- ClassAにはClassBが必要
- ClassBにはClassCが必要
次のような依存関係グラフを取得します。
ClassA --> ClassB --> ClassC
したがって、DI を使用する場合、ClassC を ClassB に、ClassB を ClassA に注入します。
しかし、ClassC が実行時の依存関係 (たとえば、ある種の戦略) であるとしましょう。実行時の依存関係を注入する方法として提案されているのは、
ClassCFactory
これで、ClassCFactory を ClassB に注入して、次のグラフを取得できます
ClassA --> ClassB --> ClassCFactory
これで ClassB にメソッドができました。このメソッドを呼び出して、ファクトリに作業を行わせることができます。例えば
ObjB.SelectC(MyRuntimeValue)
しかし、今回のアプリケーションでは、ClassB について何も知りません (おそらく、さらにいくつかの層が関係しています)。解決策の 1 つは、ClassA に SelectC を配置することです。
ObjA.SelectC(MyRuntimeValue) -(calls)-> ObjB.SelectC(MyRuntimeValue)
または、単にデメテルの法則に違反して、次のようなことを行います
ObjA.ObjB.SelectC(MyRuntimeValue)
2 番目の解決策が適切ではないことは誰もが認めると思います。しかし、最初の解決策にはいくつかの欠点もあります。特に、中間層が多い場合はなおさらです。
ファクトリを 1 レベル引き上げて ClassB を作成することもできますが、ClassB は本当に実行時の依存関係なのでしょうか? どのような解決策を提案しますか? それとも、クラスの設計が悪いのでしょうか?
私見は、必要なオブジェクトを作成するファクトリではなく、オブジェクトが実際に作業を行うために必要なものに依存することを常にお勧めします。しかし、この考えを念頭に置いて、DIコンテナは役に立たないでしょう...