Pregunta

Tengo un problema para entender cómo usar IoC en un escenario donde necesito crear objetos dinámicamente. Asumamos que tengo estas clases:

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

Entonces mi problema es la creación de Campos en los constructores. Mis campos necesitan un ICommandStack, pero las Entidades no. Solo obtienen el ICommandStack para la creación de sus campos.

Podría ser más fácil solicitar los Campos como un argumento en el constructor de cada Entidad. Pero el número de Campos podría ser > 10 para Entidades individuales. No quiero crear constructores con tantos parámetros.

Así que mi idea fue entregar un FieldFactory a los Entites:

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

Al menos el (para Entidad) innecesario ICommandStack ahora se ha ido. Pero, ¿cómo crea FieldFactory un campo? Solo se puede inyectar el ICommandStack, pero la creación de Fields aún debe realizarse a través de la palabra clave "nuevo". ¿O debería darle a la fábrica una referencia a mi contenedor DI?

¿Qué es una buena solución de diseño aquí?

¿Fue útil?

Solución

Usaría un FieldFactory e inyectaría a la fábrica una referencia al contenedor (o a una interfaz que lo abstrae si no está contento de tener una fuerte dependencia de su contenedor).

De lo contrario, son tortugas hasta el fondo. Necesita algún objeto para pedirle al contenedor una nueva instancia en algún momento. Si desea que sus campos sean inyectados con DI, entonces necesita pedirle al contenedor que los construya o usted.

Para resumir, me gustaría ir con la fábrica.

Otros consejos

En Spring (y Spring.NET) existe el concepto de un " prototype-scoped " frijol / objeto.

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

En lugar de inyectar objetos fijos y cablearlos todos juntos, un alcance prototipo creará una nueva instancia del objeto cada vez que se solicite desde el contenedor IoC. No estoy seguro de qué marco DI está usando, pero podría tener algo similar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top