Какой смысл в структурах внедрения зависимостей? - PullRequest
8 голосов
/ 12 августа 2010

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

public class CompaniesController : Controller
    { 
        private ICompaniesService _service;

        public CompaniesController()
        {
            _service = new CompaniesService();
        }

        public CompaniesController(ICompaniesService service)
        {
            _service = service;
        }

Ответы [ 7 ]

6 голосов
/ 12 августа 2010

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

Не указав реализацию внутри класса, вы можете «внедрить» реализацию во время выполнения.(В вашем примере интерфейс ICompaniesService.)«Дайте им новый объект CompaniesService».

Чтобы выполнить модульное тестирование этого класса, вы можете издеваться над нашим ICompaniesService и сами предоставить его конструктору.Это позволяет вам настроить управляемые методы на фиктивном объекте.Если вы не можете сделать это, ваши модульные тесты для CompaniesController будут ограничены использованием только одной реализации службы вашей компании, которая может попасть в действующую базу данных и т. Д., Что сделает ваши модульные тесты медленными и непоследовательными.

4 голосов
/ 12 августа 2010

Люди не используют Dependency Injection Framework для генерации кода, который вы предоставили в своем примере. Это все еще работа разработчика.

Dependency Injection Framework используется, когда кто-то вызывает конструктор. Framework будет внедрять конкретную реализацию ICompaniesService, а не разработчика, явно вызывающего конструктор.

Хотя это конкретный продукт, на главной странице nInject есть несколько действительно хороших примеров.

1 голос
/ 12 августа 2010

Из Википедия :

без понятия зависимости инъекция, потребитель, который нуждается в конкретный сервис "ICompaniesService" с целью выполнить определенную задачу будет ответственность за обработку жизненный цикл (создание, открытие и закрытие потоков, удаление и т. д.) этот сервис. Используя концепцию Внедрение зависимости, однако, Жизненный цикл услуги обрабатывается зависимость провайдер / фреймворк (обычно контейнер), а не потребитель. Таким образом, потребитель будет нуждаться только в ссылка на реализацию услуга «ICompaniesService» , которая нужна для того, чтобы выполнить необходимую задачу.

Прочтите это тоже:

Что такое внедрение зависимостей?

0 голосов
/ 01 августа 2016

Я добавлю:

Вы можете выполнить внедрение зависимостей, просто имея параметризованное определение функции.

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

Структуры внедрения зависимостей решают проблему сокращения шаблонов написания этих фабрик.

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

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

0 голосов
/ 20 августа 2010

Вам не нужно иметь DI-фреймворк, но в какой-то момент в вашей кодовой базе потребуется конкретная реализация, которая будет внедрена в ваши конструкторы / свойства. Если у вас нет DI-фреймворка, может быть очень грязно, я рекомендую взглянуть на Castle Windsor, хотя, как уже упоминалось, есть другие, которые будут выполнять те же функции. Или если бы вы могли сыграть свою роль ....:)

0 голосов
/ 12 августа 2010

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

При использовании DI бремя поиска зависимости лежит не на компоненте (как в шаблоне ServiceLoacator), но до контейнера, в котором находится компонент Бег. У шаблона есть следующие преимущества:

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

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

Есть хорошая статья Мартина Фаулера, который придумал термин DI

0 голосов
/ 12 августа 2010

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

...