Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Служба DI без зависимых служб

Автор вопроса: StellarElevenОтветов: 2

Я работаю с Ninject для реализации приложения с использованием внедрения зависимостей. Я чувствую, что у меня есть довольно полное понимание концепций, и мне очень понравилась слабосвязанная и тестируемая архитектура, которую приложение получило с помощью DI. Однако я борюсь с одним конкретным типом службы и ищу информацию о том, делаю ли я что-то неправильно или другие сталкивались с тем же.

По сути, я получаю некоторые сервисы/классы (довольно небольшое число), от которых не зависят другие сервисы. Из-за этого класс никогда не создается, даже если это требуется, поскольку он выполняет полезную роль в приложении. В качестве примера предположим, что у меня есть служба IMonkeyRepository и служба IMonkeyPopulator. Предположим, что служба IMonkeyPopulator действительно не имеет общедоступного API, и ее единственная обязанность (в соответствии с принципом единой ответственности) заключается в обнаружении обезьян в сети и заполнении ими IMonkeyRepository. Эта служба зависит от IMonkeyRepository и, возможно, некоторых других служб для обработки взаимодействия с сетью (например, данные конфигурации для портов и адресов). Однако у IMonkeyPopulator нет общедоступного API, это просто пустой интерфейс.

Это плохой дизайн или какой-то запах кода, который мне не хватает? Очевидно, я мог бы переместить эту функциональность в сам репозиторий, но мне это кажется нарушением SRP (репозиторий имеет полезные функции доступа и т. д. и фактически может быть заполнен несколькими службами). Некоторые подходы, которые я рассматривал или пробовал, но которые меня не устраивают:

  1. Сделайте так, чтобы у службы был один общедоступный метод, например Start, который необходимо вызвать, чтобы она начала работать. У этого есть недостаток, заключающийся в необходимости определения несколько произвольного места в системе для выполнения этого вызова.
  2. Привяжите службу к константе, которую я создаю при создании ядра Ninject. Это требует, чтобы я понимал, что никто не зависит от этой службы, поэтому ее нужно обрабатывать специально, что кажется неправильным.
  3. Добавьте несколько членов в службу и создайте графический интерфейс где-нибудь в моем приложении, который считывает эти значения (например, статус службы и т. д.). Очевидно, что добавление графического интерфейса в мое приложение, которое существует только по этой причине, довольно глупо (хотя иногда это полезно для отладки и т. д.).

Любые мысли или рекомендации?

dependency-injectioninversion-of-controlninjectninject-2

Ответы

Ответ 1 · рейтинг 3 · Quanta

Вы говорите, что IMonkeyPopulator зависит от IMonkeyRepository, но кажется, что должно быть наоборот? Похоже, что ваш IMonkeyRepository зависит от IMonkeyPopulator и, следовательно, может нуждаться в инъекциях. Если вы также внедрите какую-то другую службу, хорошо, но внутри IMonkeyRepository может сказать IMonkeyPopulator "запустить", чтобы в репозитории действительно что-то было? Хотя, возможно, я неправильно понимаю проблему... может быть, мне не стоит так много дурачиться :/

Ответ 2 · рейтинг 3 · Daniel Marbach

Таким образом, ваш IMonkeyPopulator является чем-то вроде ActiveObject, который прослушивает TCP-соединение в фоновом режиме и записывает эти данные в репозиторий. Я бы сказал с точки зрения приложения, что активный объект должен быть запущен и остановлен, потому что вы не хотите запускать TCP-соединение в конструкторе. Таким образом, вы можете использовать методы OnActivation и OnDeactivation в привязке для запуска и остановки службы следующим образом:

 This.Bind<IPopulatorService>().To<>().OnActivation((c, i) => i.Start()).OnDeactivation((c, i) => i.Stop())

Но все же кто-то в вашем приложении должен получить/получить IPopulatorService, чтобы создать его экземпляр в вашем приложении. Обычно я использую шаблон начальной загрузки здесь http://www.appccelerate.com/bootstrapper.html в чтобы добиться этого.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы