我有一个问题需要了解如何在需要动态创建对象的场景中使用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 ) );
}
}
所以我的问题是在构造函数中创建Fields。我的字段需要一个ICommandStack,但实体不需要。他们只获得ICommandStack来创建他们的字段。
在每个Entity的构造函数中请求Fields作为参数可能更容易。但单个实体的字段数可能> 10。我不想创建包含这么多参数的构造函数。
所以我的想法是将FieldFactory移交给Entites:
class EntityA {
public EntityA( IFieldFactory fieldFactory ) {
// create as many fields as needed via the factory
Fields.Add( fieldFactory.CreateStringField() );
}
}
至少(for Entity)不需要的ICommandStack现在已经消失了。但FieldFactory如何创建一个Field?它只能注入ICommandStack - 但是仍然需要通过'new'关键字来创建Fields。或者我应该向工厂提供我的DI容器的参考资料吗?
这里有什么好的设计解决方案?
答案 0 :(得分:3)
我使用FieldFactory并为工厂注入容器的引用(或者如果你不满意对容器的强烈依赖,那么为它抽象一个接口)。
否则,它一直是乌龟。您需要一些对象在某个时刻向容器询问新实例。如果您希望您的字段是DI注入的,那么您需要让容器构建它们或您。
总而言之,我会去工厂。
答案 1 :(得分:0)
在Spring(和Spring.NET)中,存在“原型范围”bean /对象的概念。
原型范围不是注入固定对象并将它们连接在一起,而是在IoC容器请求的任何时候创建对象的新实例。我不确定你正在使用什么DI框架,但它可能有类似的东西。