Запутался в использовании контейнера IOC, локатора сервисов и фабрики

Предположим, у меня есть BaseForm, который зависит от ILogger или IResourceManager или чего-то в этом роде. В настоящее время он решает правильную реализацию требуемой службы с помощью локатора служб, который, как я знаю, является анти-шаблоном.

  • Является ли использование инъекции конструктора правильным способом устранения такой зависимости?
  • Должен ли я регистрировать свой BaseForm (и его производные типы) в контейнере, чтобы создавать их экземпляры с разрешенными зависимостями? Разве это не все усложняет?
  • Плохо ли использовать статическую фабрику, обернутую вокруг локатора сервисов?
  • Помимо модульного тестирования, действительно ли я буду наказан за использование антипаттерна локатора служб?

Извините, что задаю сразу много вопросов. Я прочитал следующие вопросы SO и многие другие, но их чтение только усугубило мое замешательство:




Ответы (1)


Если возможно, вы всегда должны использовать внедрение зависимостей, так как оно имеет некоторые очевидные преимущества. Однако с технологиями пользовательского интерфейса не всегда возможно использовать внедрение зависимостей, поскольку некоторые технологии пользовательского интерфейса (например, в пространстве .NET, Win Forms и Web Forms) позволяют иметь только классы пользовательского интерфейса (формы, страницы, элементы управления и т. Д.). конструктор по умолчанию. В этом случае вам придется вернуться к чему-то другому, а именно к локатору услуг.

В таком случае я могу дать вам следующий совет:

  • Возвращайтесь к Service Locator только для классов пользовательского интерфейса, которые не могут быть созданы вашим контейнером с помощью внедрения зависимостей, а также для вещей, которые вы в любом случае не тестируете.
  • Постарайтесь реализовать как можно меньше логики в этих классах пользовательского интерфейса (как скромные объекты с только просмотром связанных вещей ). Это позволяет вам проводить модульное тестирование в максимально возможной степени.
  • Оберните контейнер вокруг статического метода, чтобы скрыть контейнер от остальной части приложения. Убедитесь, что вызов этого статического метода завершился ошибкой, если зависимость не может быть разрешена.
  • Разрешите все зависимости в конструкторе (по умолчанию) этого типа. Это позволяет приложению быстро выходить из строя, когда одна из его зависимостей не может быть разрешена при создании этого типа, а не позже, когда нажимается какая-либо кнопка.
  • При запуске приложения (или с помощью модульного теста) проверьте, можно ли создать все эти типы пользовательского интерфейса. Это избавляет вас от необходимости просматривать все приложение (открывая все формы), чтобы увидеть, есть ли ошибка в конфигурации DI.
  • Когда типы не могут быть построены контейнером, нет причин регистрировать их в контейнере. Если они могут быть созданы контейнером (например, с классами контроллера ASP.NET MVC), может быть полезно зарегистрировать их явно, потому что некоторые контейнеры позволяют вам проверить конфигурацию заранее, что позволит правильно выявлять ошибки конфигурации в этих типах. прочь.

Помимо модульного тестирования, есть два других важных аргумента против использования Service Locator, которые приводит Марк Земанн в его знаменитом сообщении в блоге Локатор служб - это антишаблон:

  • Service Locator «скрывает зависимости класса, вызывая ошибки времени выполнения вместо ошибок времени компиляции»
  • Service Locator «усложняет сопровождение кода»
person Steven    schedule 30.06.2012
comment
А как насчет класса, не относящегося к пользовательскому интерфейсу? Мне не хочется регистрировать все мои зависимые классы (которые не являются компонентом или службой) внутри контейнера. - person reticent; 30.06.2012
comment
Для всего остального используйте DI и убедитесь, что контейнер может их разрешить. Большинство контейнеров позволяют выполнять пакетную регистрацию, что означает, что вы можете зарегистрировать весь набор (связанных) компонентов в одном (или нескольких) операторах. Благодаря этому ваш корень композиции будет небольшим и удобным в обслуживании. - person Steven; 30.06.2012