Лучшие практики для контейнера IOC

Слово предупреждения: если вы поместите файлы конфигурации в папку WEB-INF/classes, а ваша среда IDE, скажем, Eclipse, выполняет очистку / перестройку, она будет уничтожать ваши файлы conf, если они не были в исходном каталоге Java. Большой ответ BalusC намекает на то, что в варианте 1, но я хотел добавить акцент.

Я усвоил, что если вы «скопируете» веб-проект в Eclipse, он очистит / перестроит из любых исходных папок , В моем случае я добавил «связанный исходный каталог» из нашей Java-библиотеки POJO, он будет скомпилирован в папку WEB-INF/classes. Выполнение чистых / перестроек в этом проекте (а не в проекте веб-приложений) вызвало ту же проблему.

Я думал о том, чтобы поместить мои confs в папку POJO src, но эти confs - все для сторонних библиотек (например, Quartz или URLRewrite), которые находятся в папке WEB-INF/lib, так что это не имеет смысла , Я планирую протестировать его размещение в папке «src» веб-проектов, когда я обхожусь к нему, но эта папка в настоящее время пуста, и в ней есть файлы conf, которые выглядят inelegant.

Итак, я голосую за то, в WEB-INF/commonConfFolder/filename.properties, next в папку классов, которая является параметром Balus 2.

26
задан Ryu 3 April 2009 в 15:11
поделиться

6 ответов

Поместите контейнер IOC на самый высокий уровень / точку входа в процесс и используйте его для внедрения зависимостей во все, что находится под ним.

13
ответ дан 28 November 2019 в 07:20
поделиться

можно зарегистрировать контейнер сам по себе и вводить его как любое свойство зависимости, как так:

IUnityContainer container = new UnityContainer();
container.RegisterInstance<IUnityContainer>(container);

классы, которые должны получить доступ к нему, будут иметь следующее свойство:

private IUnityContainer unityContainer;
[Dependency]
public IUnityContainer UnityContainer
{
    get { return unityContainer; }
    set { unityContainer = value; }
}

таким образом, контейнер введен каждый раз, когда экземпляр такого класса решен/создан.

Это более гибко, поскольку это работает на несколько контейнеров в рамках того же приложения, которое не было бы возможно с шаблоном "одиночка".

6
ответ дан lcvinny 25 September 2019 в 07:24
поделиться

Если всем Вашим объектам нужна ссылка на контейнер затем, необходимо изучить переделку кода некоторые. В то время как все еще предпочтительный для вызова нового везде это все еще рассеивает ответственность создания Ваших графов объектов всюду по Вашему коду. С таким использованием это, кажется мне, используется больше как ServiceLocator вместо Контейнера МОК.

2
ответ дан toad 25 September 2019 в 07:24
поделиться

Другим вариантом будет использование CommonServiceLocator , хотя это может быть бессмысленным косвенным указанием, вы можете использовать ServiceLocator.Current в качестве экземпляра, известного всем классам

0
ответ дан 28 November 2019 в 07:20
поделиться

У меня есть сообщение на эту тему в моем блоге, где я использую что-то вроде ответа t3mujin. Не стесняйтесь использовать его (не беспокойтесь, что это связано с sharepoint ... это не имеет значения):

http://johanleino.spaces.live.com/blog/cns!6BE273C70C45B5D1!213.entry

0
ответ дан 28 November 2019 в 07:20
поделиться

ИМХО, не рекомендуется вводить весь контейнер в класс или иметь статическую службу IoC для всего приложения локатор.

Вы хотите видеть из конструктора класса (назовем его Foo), какие службы / объекты он использует для выполнения работы. Это улучшает ясность, тестируемость и дегазируемость.

Допустим, Foo нужна только служба электронной почты, но я передаю весь контейнер и где-то в коде служба электронной почты получает разрешение из контейнера. В этом случае уследить будет очень сложно. Вместо этого лучше внедрить почтовую службу напрямую, чтобы более четко указать зависимости Foo.

Если Foo нужно создать несколько экземпляров почтовой службы, лучше создать и внедрить EmailServiceFactory (через контейнер IoC), который будет создавать необходимые экземпляры на лету.

В последнем случае зависимости Foo по-прежнему указываются как можно более конкретными - только те, которые может создать EmailServiceFactory. Если бы я внедрил весь контейнер, было бы непонятно, какие услуги, предоставляемые им, являются точными зависимостями Foo.

Теперь, если я позже захочу предоставить другие экземпляры почтовой службы, я заменю их внутри EmailServiceFactory. Я мог бы поменять местами и всю фабрику, если все сервисы, которые она создает, нужно поменять местами (например, во время тестирования).

Таким образом, ценой создания одного дополнительного класса (фабрики) я получил гораздо более чистый код и выиграл Не нужно беспокоиться о любопытных ошибках, которые могут возникнуть при использовании глобальной статики. Кроме того, при поставке моков для тестирования я точно знаю, что им нужно, и не делаю этого. • Имитировать типы всего контейнера.

Этот подход также имеет то преимущество, что теперь, когда модуль инициализирован (применяется только к Prism / Modularity), ему не нужно регистрировать все типы объектов он поставляется с контейнером IoC. Вместо этого он может просто зарегистрировать свой ServiceFactory, который затем предоставляет эти объекты.

Для ясности, класс инициализации модуля (реализует IModule) должен по-прежнему получать контейнер IoC для всего приложения в своем конструкторе, чтобы предоставлять услуги, которые потребляются другими модулей, но контейнер не должен вторгаться в классы модуля.

Наконец, мы имеем еще один прекрасный пример того, как дополнительный уровень косвенного обращения решает проблему.

когда модуль инициализируется (применяется только к Prism / Modularity), ему не нужно регистрировать все типы объектов, которые он поставляет с контейнером IoC. Вместо этого он может просто зарегистрировать свой ServiceFactory, который затем предоставляет эти объекты.

Для ясности, класс инициализации модуля (реализует IModule) должен по-прежнему получать контейнер IoC для всего приложения в своем конструкторе, чтобы предоставлять услуги, которые потребляются другими модулей, но контейнер не должен вторгаться в классы модуля.

Наконец, мы имеем еще один прекрасный пример того, как дополнительный уровень косвенного обращения решает проблему.

когда модуль инициализируется (применяется только к Prism / Modularity), ему не нужно регистрировать все типы объектов, которые он поставляет с контейнером IoC. Вместо этого он может просто зарегистрировать свой ServiceFactory, который затем предоставляет эти объекты.

Для ясности, класс инициализации модуля (реализует IModule) должен по-прежнему получать контейнер IoC для всего приложения в своем конструкторе, чтобы предоставлять услуги, которые потребляются другими модулей, но контейнер не должен вторгаться в классы модуля.

Наконец, мы имеем еще один прекрасный пример того, как дополнительный уровень косвенного обращения решает проблему.

22
ответ дан 28 November 2019 в 07:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: