简体   繁体   English

IoC:如何动态创建对象

[英]IoC: How to create objects dynamically

I have a problem to understand how to use IoC in a scenario where I need to create objects dynamically. 我有一个问题需要了解如何在需要动态创建对象的场景中使用IoC。 Lets assume I have this classes: 让我们假设我有这个类:

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 ) );
  }
}

So my problem is the creation of Fields in the constructors. 所以我的问题是在构造函数中创建Fields。 My Fields need an ICommandStack, but the Entities do not. 我的字段需要一个ICommandStack,但实体不需要。 They only get the ICommandStack for the creation of their Fields. 他们只获得ICommandStack来创建他们的Fields。

It could be easier to request the Fields as an argument in each Entity's constructor. 在每个Entity的构造函数中请求Fields作为参数可能更容易。 But the number of Fields could be >10 for single Entities. 但单个实体的字段数可能> 10。 I don't want to create constructors with so many parameters. 我不想创建具有这么多参数的构造函数。

So my idea was to hand over a FieldFactory to the Entites: 所以我的想法是将FieldFactory移交给Entites:

class EntityA {
  public EntityA( IFieldFactory fieldFactory ) {
    // create as many fields as needed via the factory
    Fields.Add( fieldFactory.CreateStringField() );
  }
}

At least the (for Entity) unneccessary ICommandStack is now gone. 至少(for Entity)不需要的ICommandStack现在已经消失了。 But how does the FieldFactory create a Field? 但FieldFactory如何创建一个Field? It only can get the ICommandStack injected - but the creation of Fields has still to be done via the 'new' keyword. 它只能注入ICommandStack - 但是仍然需要通过'new'关键字来创建Fields。 Or should I give the factory a reference to my DI-container? 或者我应该向工厂提供我的DI容器的参考?

What is a good design solution here? 这里有什么好的设计方案?

I'd use a FieldFactory and inject the factory with a reference to the container (or to an interface that abstracts it if you are not happy with taking a strong dependency on your container). 我将使用FieldFactory并向工厂注入对容器的引用(或者如果您不满意对容器采取强烈依赖,则将其抽象到一个接口)。

Otherwise, it's turtles all the way down. 否则,它一直是乌龟。 You need some object to ask the container for a new instance at some point. 您需要一些对象在某个时刻向容器询问新实例。 If you want your fields to be DI-injected, then you need to ask the container to build them or you. 如果您希望您的字段是DI注入的,那么您需要让容器构建它们或您。

So to summarize, I'd go with the factory. 总而言之,我会去工厂。

In Spring (and Spring.NET) there is the concept of a "prototype-scoped" bean/object. 在Spring(和Spring.NET)中,存在“原型范围”bean /对象的概念。

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

Rather than injecting fixed objects and wiring them all together, a prototype scope will create a new instance of the object anytime it's requested from the IoC container. 而不是注入固定对象并将它们连接在一起,原型范围将在IoC容器请求的任何时候创建对象的新实例。 I'm not sure what DI framework you're using, but it might have something similar. 我不确定你正在使用什么DI框架,但它可能有类似的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM