IoC: Como criar objetos dinamicamente
-
03-07-2019 - |
Pergunta
Eu tenho um problema para entender como usar IoC em um cenário onde eu preciso para criar objetos dinamicamente. Vamos supor que eu tenho este 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 ) );
}
}
Então, o meu problema é a criação de campos nos construtores. Meus Campos precisa de uma ICommandStack, mas as entidades não. Eles só obter o ICommandStack para a criação de seus campos.
Ele poderia ser mais fácil para solicitar os campos como um argumento no construtor de cada entidade. Mas o número de campos poderia ser> 10 para entidades individuais. Eu não quero criar construtores com tantos parâmetros.
Assim, a minha ideia era mão sobre um FieldFactory aos Entites:
class EntityA {
public EntityA( IFieldFactory fieldFactory ) {
// create as many fields as needed via the factory
Fields.Add( fieldFactory.CreateStringField() );
}
}
Pelo menos o (a Entidade) unneccessary ICommandStack é ido agora. Mas como o FieldFactory criar um campo? Ele só pode obter o ICommandStack injetado - mas a criação de campos ainda tem de ser feito através da palavra-chave 'novo'. Ou devo dar a fábrica uma referência ao meu DI-container?
O que é uma boa solução de projeto aqui?
Solução
eu usaria um FieldFactory e injetar fábrica com uma referência para o contêiner (ou a uma interface que os resumos se você não está feliz com a tomada de uma dependência forte em seu recipiente).
Caso contrário, é tartarugas toda a maneira para baixo. Você precisa de algum objeto para pedir o recipiente para uma nova instância em algum ponto. Se você quer que seus campos a serem DI-injetado, então você precisa perguntar o recipiente para construí-los ou você.
Assim, para resumir, eu iria com a fábrica.
Outras dicas
Na Primavera (e Spring.NET) existe o conceito de um "escopo de protótipo" feijão / objeto.
Ao invés de injetar objetos fixos e fiação-los todos juntos, um escopo protótipo irá criar uma nova instância do objeto qualquer momento é solicitado ao contêiner IoC. Eu não tenho certeza do que quadro DI que você está usando, mas que poderia ter algo similar.