Почему в Simple Injector нет такой абстракции IContainer, как Unity?

Я использовал Unity для своего последнего проекта и в целом остался доволен. Но тесты заставляют меня думать, что я могу использовать Simple Injector для своего следующего проекта.

Однако у Simple Injector, похоже, нет интерфейса для своего класса Container. Это означает, что всякий раз, когда я хочу использовать контейнер в методе, я не могу имитировать контейнер для модульного тестирования.

Меня смущает, как инструмент, который действительно функционирует на основе интерфейсов, сам не создает интерфейс для контейнера. Я знаю, что классические методы внедрения зависимостей не нуждаются в контейнере больше, чем для запуска. (В остальном используется инъекция конструктора.) Но я обнаружил, что, когда резина попадает в дорогу, это не всегда может быть правдой. Иногда контейнер нужен просто для того, чтобы «разрешить» код.

Если я выберу Simple Injector, то этот код, похоже, станет сложнее для модульного тестирования.

Я прав? Или я что-то упускаю?


person Vaccano    schedule 25.04.2013    source источник
comment
Почему бы не использовать абстрактную фабрику вместо внедрения контейнера?   -  person onof    schedule 07.05.2013


Ответы (2)


Simple Injector не содержит абстракции IContainer, потому что:

person Steven    schedule 25.04.2013
comment
Я не хочу использовать контейнер в своих тестах. Я хочу провести модульное тестирование метода, использующего контейнер. В этом случае я не могу имитировать контейнер, чтобы не использовать полную логику SimpleInjector. - person Vaccano; 26.04.2013
comment
Хорошо, мы собираемся попробовать это иначе, чем то, как мы делаем Unity. Для Unity мы имитируем IContainer, чтобы возвращать mocks. Таким образом, Unity не используется (не тестируется) нашими модульными тестами. Мы собираемся попробовать SimpleInjector. Мы передадим тестовую версию контейнера конструктору тестируемого объекта (при необходимости). Эта тестовая версия будет настроена на возврат моков. По сути, мы будем использовать SimpleInjector в наших тестах для возврата моков, но в производстве он будет возвращать объекты, которые были настроены при запуске. Я чувствую, что должен попробовать, потому что SimpleInjector чертовски быстр !!! - person Vaccano; 26.04.2013
comment
Но почему у земли этот класс зависит от контейнера? Классы, у которых есть (достаточно) логики для тестирования, не должны напрямую зависеть от контейнера. Только компоненты инфраструктуры (которые являются частью вашего корня композиции) должны иметь зависимость от контейнера или абстракции контейнера. У вас явно возникли проблемы с тестированием вашей системы, потому что вы нарушаете это правило. - person Steven; 27.04.2013
comment
В большинстве случаев контейнер нам не нужен. (Хотя иногда мы считаем полезным ограничить количество параметров в конструкторе.) Но мы сталкивались со случаями, когда нам нужен контейнер, чтобы разрешить нам встроенный объект. И это невозможно сделать с помощью инъекции конструктора. Вот где очень полезно иметь IContainer. - person Vaccano; 27.04.2013
comment
Если вы вводите контейнер, чтобы ограничить количество параметров, это, вероятно, означает, что этот класс делает слишком много; нарушает принцип единой ответственности. Пожалуйста, пересмотрите свою стратегию. Я увлечен борьбой с таким злоупотреблением контейнером. Если вы сомневаетесь, опубликуйте несколько примеров из реальной жизни класса, который получает контейнер, введенный herr на SO, или напишите мне напрямую. С удовольствием объясню, как можно изменить дизайн таким образом, чтобы проблема исчезла. - person Steven; 27.04.2013
comment
Все параметры связаны с проблемами единой ответственности. У меня есть IPatientService, IDoctorService, IConfigService, IRegionAdapter, IRequistionHelpService, ISearchService и еще несколько. Если у меня есть часть пользовательского интерфейса, которая требует их всех, я получаю множество параметров конструктора. Честно говоря, я не против. Но некоторые члены моей команды жалуются на это. - person Vaccano; 27.04.2013
comment
Этот пользовательский интерфейс явно нарушает SRP, и это приведет к проблемам с ремонтопригодностью, как и классы с именами * Service, * Manager, * Helper и т. Д. Мы называем их Классы Бога. Ваше приложение может выиграть от другого дизайна. Прочтите эту статью и эту статью, чтобы получить некоторые идеи о том, как улучшить дизайн вашего приложения. - person Steven; 27.04.2013
comment
Может быть, в идеальном мире у вас может быть пользовательский интерфейс с единственной ответственностью. К сожалению, мой пользовательский интерфейс должен работать так, как того требует мой владелец продукта. И часто им нужен пользовательский интерфейс, который поможет им в выполнении нескольких задач. - person Vaccano; 08.05.2013
comment
Это по-прежнему не заставляет вас использовать один компонент пользовательского интерфейса. Вы можете по-прежнему создавать этот пользовательский интерфейс, используя несколько пользовательских элементов управления, частичные элементы или что-то еще, что называется в технологии пользовательского интерфейса, которую вы используете. Вы можете составить этот экран из нескольких частей. - person Steven; 08.05.2013
comment
Вот что мы делаем. Но пользовательскому интерфейсу, который содержит все компоненты, по-прежнему нужны все ссылки. - person Vaccano; 08.05.2013

Я думаю, что приведенный здесь ответ полностью основан на признании того, что ServiceLocator является анти-шаблоном, который, в свою очередь, я не считаю, что это глобально признано истинным. См. Раздел «Поддержка расширений Windows Workflow Foundation».

Ссылка на антишаблон (и ее два обновления) также может быть слабой ... последнее обновление заявляет о нарушении инкапсуляции («избавляя вас от бремени необходимости понимать каждую деталь реализации каждого фрагмента кода в вашей кодовой базе». ), в то же время утверждая, что предварительное знание зависимостей как-то отличается для этого утверждения, чем обнаружение их с помощью модульных тестов. В любом случае вам нужно будет знать, что подарить.

В общем, если вы хотите следовать шаблону Locator, либо используйте его IServiceProvider, либо упростите заполнение контейнера (до синглтона) и создайте для него статическую оболочку.

person Craig Brunetti    schedule 07.09.2016