IoC:オブジェクトを動的に作成する方法
-
03-07-2019 - |
質問
オブジェクトを動的に作成する必要があるシナリオでIoCを使用する方法を理解するのに問題があります。このクラスがあると仮定しましょう:
abstract class Field {
public Field( ICommandStack commandStack ) {}
}
abstract class Entity {
public readonly Collection<Field> Fields { get; }
}
class EntityA {
public EntityA( ICommandStack commandStack ) {
Fields.Add( new StringField( commandStack ) );
}
}
class EntitiyB {
public EntityB( ICommandStack commandStack ) {
Fields.Add( new IntField( commandStack ) );
Fields.Add( new IntField( commandStack ) );
Fields.Add( new IntField( commandStack ) );
}
}
だから私の問題は、コンストラクターでのフィールドの作成です。私のフィールドにはICommandStackが必要ですが、エンティティには必要ありません。彼らは、フィールドの作成のためにICommandStackのみを取得します。
各エンティティのコンストラクタの引数としてフィールドをリクエストする方が簡単かもしれません。ただし、単一のエンティティのフィールド数は&gt; 10です。あまり多くのパラメーターを持つコンストラクターを作成したくありません。
したがって、私の考えはFieldFactoryをエンティティに引き渡すことでした:
class EntityA {
public EntityA( IFieldFactory fieldFactory ) {
// create as many fields as needed via the factory
Fields.Add( fieldFactory.CreateStringField() );
}
}
少なくとも(エンティティの場合)不要なICommandStackはなくなりました。しかし、FieldFactoryはどのようにしてフィールドを作成しますか? ICommandStackを注入することしかできませんが、Fieldsの作成は「new」キーワードを介して行う必要があります。または、DIコンテナーへの参照を工場に提供する必要がありますか?
ここでの優れた設計ソリューションは何ですか?
解決
FieldFactoryを使用して、コンテナ(または、コンテナへの強い依存関係に満足できない場合は、それを抽象化するインターフェイス)への参照をファクトリに挿入します。
それ以外の場合、カメはずっと下にいます。ある時点でコンテナに新しいインスタンスを要求するオブジェクトが必要です。あなたのフィールドにDIを注入したい場合は、コンテナにそれらを作成するよう依頼する必要があります。
要約すると、工場に行きます。
他のヒント
Spring(およびSpring.NET)には、「プロトタイプスコープ」という概念があります。 Bean /オブジェクト。
固定オブジェクトを注入してそれらをすべて接続するのではなく、プロトタイプスコープは、IoCコンテナーから要求されるたびにオブジェクトの新しいインスタンスを作成します。使用しているDIフレームワークはわかりませんが、似たようなものがあるかもしれません。