Внедрение зависимостей с неклассами - PullRequest
2 голосов
/ 19 ноября 2011

Я немного новичок в инъекции зависимостей. Я настроил его для некоторых классов, которые передают свои зависимости как параметры в конструкторе, но у меня есть некоторые конструкторы, которые принимают примитивы, такие как String или boolean. Очевидно, что они должны быть удалены из конструктора, если я собираюсь использовать Dependency Injection для этого класса.

Для такого случая, что такое «лучшая» практика? Заставить конструктор просто взять зависимости и предоставить метод установки для всех примитивов, которые нужны классу?

Ответы [ 3 ]

4 голосов
/ 19 ноября 2011

Очевидно, что они должны быть удалены из конструктора, если я хочу использовать Dependency Injection для этого класса

Нет, не "Очевидно". Вы можете сохранить эти параметры, а также иметь введенные зависимости.

Если класс требует эти параметры для правильной инициализации, они должны быть частью конструктора.

2 голосов
/ 19 ноября 2011

Мое наблюдение состоит в том, что в большинстве случаев классы, имеющие конструктор, который принимает как зависимости, так и примитивы, нарушают Принцип единой ответственности или, по крайней мере, приводят к менее чистому проекту, что приводит к контейнеру конфигурации, которые являются более хрупкими и трудными для понимания.

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

Есть несколько способов изменить дизайн, чтобы решить эту проблему:

  1. В случае, если вы нарушаете SRP, извлеките код в его собственный тип. Возьмем, к примеру, этот пример , где NotifyCustomerHandler принимает string notificationServiceUrl, тогда как этот string должен был быть заключен в некоторый тип NotificationService.
  2. Другой вариант - извлечь значения конфигурации типа в его собственный тип. В случае NotifyCustomerHandler он может зависеть от INotifyCustomerHandlerConfiguration. Раньше у меня был один интерфейс IMyApplicationConfiguration со всеми значениями конфигурации, которые требовались приложению, но я пришел к выводу, что это плохая идея. Это нарушает принцип разделения интерфейсов , и ваши модульные тесты начнут страдать с точки зрения читабельности и удобства обслуживания.
  3. Когда вы не нарушаете SRP и вставляете объект конфигурации нецелесообразно (когда у вас есть один примитив или у вас слишком много конфигурационных интерфейсов, или вам просто не нравится эта опция), вы можете изменить этот конструктор аргументы в пользу публичной собственности. Это позволит вам (с большинством контейнеров) зарегистрировать делегата, который будет настраивать экземпляр после создания, таким образом, чтобы компилятор мог проверить это для вас.
1 голос
/ 20 ноября 2011

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

Любой нетривиальный контейнер будет обслуживать этот сценарий и позволит вам сделать это. Вот, например, как Касл Виндзор делает это .

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