IoC: как создавать объекты динамически - PullRequest
4 голосов
/ 04 мая 2009

У меня проблема с пониманием того, как использовать 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 ) );
  }
}

Итак, моя проблема - создание полей в конструкторах. Мои поля нуждаются в ICommandStack, а сущности - нет. Они только получают ICommandStack для создания своих полей.

Может быть проще запросить Поля в качестве аргумента в конструкторе каждой сущности. Но количество полей может быть> 10 для отдельных лиц. Я не хочу создавать конструкторы с таким количеством параметров.

Итак, моя идея состояла в том, чтобы передать FieldFactory Entites:

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

По крайней мере (для Entity) ненужного ICommandStack теперь нет. Но как FieldFactory создает поле? Он может только внедрить ICommandStack, но создание полей все еще должно выполняться с помощью ключевого слова «new». Или я должен дать фабрике ссылку на мой DI-контейнер?

Какое здесь хорошее дизайнерское решение?

Ответы [ 2 ]

3 голосов
/ 04 мая 2009

Я бы использовал FieldFactory и внедрил бы фабрику со ссылкой на контейнер (или на интерфейс, который абстрагирует его, если вы недовольны сильной зависимостью от вашего контейнера).

В противном случае, это черепахи вниз. Вам нужен какой-то объект, чтобы запросить у контейнера новый экземпляр в какой-то момент. Если вы хотите, чтобы ваши поля вводились с помощью DI, вам нужно попросить контейнер создать их или вас.

Итак, подведу итог, я бы пошел с завода.

0 голосов
/ 04 мая 2009

В Spring (и Spring.NET) существует концепция bean-объекта / объекта с прототипом.

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

Вместо того, чтобы вставлять фиксированные объекты и соединять их все вместе, область действия прототипа будет создавать новый экземпляр объекта каждый раз, когда его запрашивают из контейнера IoC. Я не уверен, какой DI-фреймворк вы используете, но он может иметь что-то похожее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...