IoC:如何动态创建对象

时间:2009-05-04 15:10:24

标签: c# inversion-of-control

我有一个问题需要了解如何在需要动态创建对象的场景中使用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容器的参考资料吗?

这里有什么好的设计解决方案?

2 个答案:

答案 0 :(得分:3)

我使用FieldFactory并为工厂注入容器的引用(或者如果你不满意对容器的强烈依赖,那么为它抽象一个接口)。

否则,它一直是乌龟。您需要一些对象在某个时刻向容器询问新实例。如果您希望您的字段是DI注入的,那么您需要让容器构建它们或您。

总而言之,我会去工厂。

答案 1 :(得分:0)

在Spring(和Spring.NET)中,存在“原型范围”bean /对象的概念。

http://static.springframework.org/spring/docs/2.0.x/reference/beans.html#beans-factory-scopes-prototype

原型范围不是注入固定对象并将它们连接在一起,而是在IoC容器请求的任何时候创建对象的新实例。我不确定你正在使用什么DI框架,但它可能有类似的东西。