Являются ли основы для инъекций зависимостей дополнительным уровнем перенаправления?

Вы находите, что каркасы инъекций зависимостей делают код более сложным? Оказывает ли косвенное влияние преимущество?

Ответ 1

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

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

Верно, что вы не можете видеть, какая реализация используется при просмотре кода. Вы увидите ссылку на интерфейс. Хорошая среда IDE может иметь функциональность для просмотра всех реализаций для определенного интерфейса, поэтому используйте это в своих интересах.

Ответ 2

Для нетривиальных приложений "enterpriseisey", да, это того стоит. Перед базами DI каждый магазин реализовал свой собственный причудливый класс "ServiceLocator" в некоторой внутренней библиотеке, которую использовали другие их проекты. Таким образом, у вас были звонки на эту вещь, замусоренную по всей кодовой базе.

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

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

Подробнее о сравнении DI с ServiceLocator см. Fowler Инверсия контейнеров управления и шаблон впрыска зависимостей

Ответ 3

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

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

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

Р

Ответ 4

Преимущества DI трудно понять с первого взгляда. Показательность является наиболее очевидной. Я попытаюсь собрать очень короткий пример, чтобы проиллюстрировать эти преимущества. Представьте, что ваше приложение использует определенный поставщик баз данных. Если вы сохраните весь свой код, посмотрите только интерфейс поставщика БД, вы легко переключитесь с одной реализации на другую. Теперь, если вы создаете корпоративные приложения, крайне не желательно, что конкретный поставщик БД может быть очень желательным, например, когда клиент уже приобрел лицензию DB. На самом деле это зависит от интерфейса, а не от реализации. Все идет нормально. Теперь мне нужно как-то схватить свой конкретный объект. Мой конкретный объект может быть примером конкретного поставщика. Как мне это сделать?

  • Использовать новое для создания объекта.
    Я буду должны перекомпилировать проект в чтобы его распространить. Огромный недостаток: придется тестировать, развертывать, поддерживать новую ветвь кода и т.д.
  • Используйте Factory.
    Мой код будет посыпать с кодом, который захватывает factory и получает экземпляр. Как и я придется возвращать общий экземпляр и применить его к типу объект, который я ожидаю. Если нет, у меня будет для изменения интерфейса Factory время Я добавляю новый объект, созданный factory.
  • Использовать локатор сервисов.
    Подобные как 2. Только, в зависимости от Сервиса Локатор может быть не всегда вокруг, как Java JNDI.

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

Ответ 5

Мне сначала понравилась идея инфраструктуры инъекций зависимостей, но помимо поддержки модульного тестирования я все еще не убежден в преимуществах использования этого. Это означает еще один фреймворк/API/метод для тех, кто берет мой проект, чтобы учиться, и в некоторых случаях может быть более подробным. Вы можете найти отличные ответы на все плюсы и минусы этих двух конкурирующих записей в блогах.

Для инфраструктуры DI

Против DI Framework

Нижняя строка сводится к тому, что она действительно уменьшает сцепление и увеличивает сплоченность, или это просто подталкивает проблемы под поверхностью. В моем проекте прямо сейчас я не вижу в этом большой необходимости, даже для поддержки модульного тестирования. Если бы вы собирались выбрать один для С#, я бы очень рекомендовал Ninject. Он легкий, простой и полностью плавно настроенный... нет XML! Sweeet:)

Ответ 6

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

Если переходить по исходному коду слишком сложно, получите Resharper и все в порядке.

Ответ 7

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

Однако Inversion of Control - это не единственный способ пойти сюда. Коллега добился этого, написав собственную реализацию JNDI. Это заняло довольно много времени, чтобы выиграть меня, но это фантастика и имеет небольшую часть конфигурации типичного проекта Spring.

Ответ 8

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

Я знаю, что всякий раз, когда я пытался использовать инфраструктуру DI, это по существу все, что я действительно использовал для этого. Я также видел случаи, когда люди переносят свой контейнер DI в статический класс IoC для создания объектов вниз в иерархии, и, на мой взгляд, этот вид побеждает цель; не так ли? Вернемся к тому, чтобы быть локатором сервисов в этот момент? Наверное, я не совсем понимаю, насколько практично. Я говорю "махинации", вы используете рефлексию и принимаете большой пусковой удар, чтобы сделать то же самое.

Вы не можете устранить зависимости, но вы уверены, что можете запутать их из файла конфигурации XML. В какой-то момент что-то будет называться new. Вы действительно собираетесь поменять реализацию интерфейса без повторной компиляции или повторного тестирования вашего приложения? Если нет, держите его простым. Приятно нажать "Найти определение" и увидеть что-то действительно получающее экземпляр в классе локатора сервисов с явным синглом или ThreadStatic или другим поведением.

Только мои два цента - я все еще довольно новичок в инфраструктурах DI, но мой текущий ход мысли: инверсия управления полезна, но сами реальные рамки, вероятно, только для очень больших проектов.

Ответ 9

Я думаю, что преимущество зависит от того, как вы его используете.

Например, в моем текущем проекте мы используем dep inj для ввода различных элементов в зависимости от конфигурации приложения, в частности модульного тестирования. Хорошим примером может быть то, что в производственной системе используется реальная реализация "входа", но при использовании модульных тестов используется "логин", который всегда возвращает true/valid для имени входа в систему, но нет других.