Страх использования инфраструктуры внедрения зависимостей - PullRequest
4 голосов
/ 25 августа 2009

Я читал об основах внедрения зависимостей. Я действительно влюбился в идею разделения проблем и позволения объектам выполнять свою основную работу - это, несомненно, превосходный и давний принцип проектирования!

Однако чем больше я читаю в DI-фреймворках, тем больше я волнуюсь: 1) в том, как они «автоматически» разрешают зависимости 2) Об экстремальных сложностях, вносимых в файлы конфигурации

По пункту 2 я видел, как мои клиенты тратили миллионы долларов на обучение людей продуктам, значительная часть которых заключалась в том, как «не» прикасаться к файлам конфигурации. Администраторы теперь боятся этих файлов конфигурации.

Тем не менее, я вижу другой шаблон, называемый локаторами сервисов, где я мог бы красиво собрать все «глобальные» сервисы, которые мне нужны в начале моего приложения (может быть хост приложения или контекст приложения или что-то еще). Сделайте этот сервисный локатор глобально доступным и вуаля!

Однако я вижу, что при использовании подхода Service Locator будет меньше гибкости, когда мне потребуется более одного типа «глобального» сервиса, основанного на каком-то критерии (известно кому?)!

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

Являются ли мои опасения подлинными? Кто-нибудь еще чувствует то же самое? Если да, то есть ли хорошая альтернатива для таких огромных "каркасов"?

Ответы [ 6 ]

3 голосов
/ 25 августа 2009

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

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

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

Основной принцип классов с поддержкой DI состоит в том, что они не ссылаются на код инфраструктуры. Это противоположность паттерну сервис-локатора. Основным недостатком Service Locator является то, что, помимо добавления сложности к классам, которые ссылаются на контейнер, нет возможности изменить , какая версия зависимости разрешена.

С "чистыми" классами, которые не ссылаются на контейнер, разрешенная версия любой данной зависимости является внешней по отношению к внедряемому классу.

2 голосов
/ 25 августа 2009

Если вы действительно думаете о том, чтобы пойти по пути внедрения зависимостей, я настоятельно рекомендую быстро прочитать превосходную статью Мартина Фаулера о внедрении зависимостей:

http://martinfowler.com/articles/injection.html

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

  1. Модульное тестирование с глобальными шаблонами - отстой. Шаблоны внедрения зависимостей легко поддаются простому модульному тестированию и особенно тестированию фиктивных объектов. В случае одноэлементного типа у вас теперь есть все эти модульные тесты, для работы которых все еще требуется глобальное состояние. С помощью внедрения зависимостей вы можете создавать фиктивные объекты конфигурации для конкретного теста, которые вы передаете в свои тесты. Я не могу переоценить, насколько легче это делает модульное тестирование. Еще одна отличная статья под названием «Эндотестирование: модульное тестирование с использованием фиктивных объектов»: http://connextra.com/aboutUs/mockobjects.pdf

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

  3. Как только вы пройдете небольшой путь по пути внедрения без зависимостей, пути назад не будет. Переход от внедрения зависимости к некоторому глобализированному шаблону раздражает, но выполним на пошаговой основе. Попытка перейти от глобализированного шаблона к внедрению зависимостей - это кошмар. Я продолжаю хотеть сделать это в нашем проекте, и я просто не могу. Это займет целый цикл разработки.

В любом случае, надеюсь, что статья и опыт помогут вам принять решение. Я далеко иду по пути, по которому ты думаешь идти вниз, и мне хотелось бы, чтобы вместо этого мы выбрали путь внедрения зависимости: -D

2 голосов
/ 25 августа 2009

Как упоминал Нейт, «магия» не обязательна; Вы можете настроить все вручную, если хотите.

Я бы изначально (или навсегда!) Избегал файлов конфигурации и настраивал контейнер в коде. Это, как правило, гораздо легче читать и поддерживать. Большую часть времени вам не нужны оперативные изменения конфигурации. Клиенты не могут трогать файлы конфигурации, потому что они не существуют.

Сервисные локаторы имеют свои минусы; с одной стороны, они имеют тенденцию связывать ваши классы с локаторным классом / каркасом. Хорошая структура DI позволит вам использовать Plain Old Objects; в вашем проекте может быть только один класс, который на самом деле использует структуру DI / IoC.

StructureMap и Unity довольно просты; дать им попытку. Начните с малого.

Вот очень простой пример с Unity (включая встроенную конфигурацию):

using Microsoft.Practices.Unity;

static void Main()
{
    using (IUnityContainer container = new UnityContainer())
    {
        container.RegisterType<IRobot, MrRoboto>();

        Console.WriteLine("Asking Unity container to give us a Model...");

        Model model = container.Resolve<Model>();
        model.MoveRobot();
    }
}

// class Model

public Model(IRobot robot)
{
    // Unity will hand the constructor an instance of MrRoboto!
}
1 голос
/ 25 августа 2009

Ни один из них не является «обязательным» для DI - это опции, предоставляемые некоторыми платформами DI. Лично мне не нравится «автоматическая» инъекция - я вижу, что она работает для действительно небольших проектов, но вызывает проблемы в более крупных проектах. Что касается пункта № 2 - я не уверен, что понял - я в основном использовал Spring. Spring предоставляет опции конфигурации XML и Java. Предоставляет вложенные конфигурации. Если есть часть конфигурации, которую вы не хотите, чтобы кто-либо изменял, и есть часть, которую вы делаете - разделяете их на отдельные файлы конфигурации - или делаете «изменяемый» один XML и другой Java. Spring также поддерживает использование значений из файлов свойств, и это все, что я ожидаю от администраторов - администраторы не программисты - они не должны «перемонтировать» ваше приложение - просто предоставляя соответствующие опции.

0 голосов
/ 25 августа 2009

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

0 голосов
/ 25 августа 2009

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

Например, у меня есть один файл конфигурации для разработки, один для тестирования и один для производства.

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

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

Spring имеет хорошую настройку для DI, хотя он и не легкий.

Я обнаружил, что Unity Framework не является тривиальным для изучения, но как только вы его используете, довольно легко добавлять новые классы для инъекций.

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

...