Главная страница   /   5.5. Резюме (Внедрение зависимостей в .NET

Внедрение зависимостей в .NET

Внедрение зависимостей в .NET

Марк Симан

5.5. Резюме

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

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

  • Меня зовут Марк Симан, и я использовал Control Freak.
  • Меня зовут Марк Симан, и я использовал Bastard Injection.
  • Меня зовут Марк Симан, и я использовал Constrained Construction.
  • Меня зовут Марк Симан, и я использовал Service Locator.

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

Первая и самая опасная привычка, от которой стоит избавиться, это мнимая необходимости иметь прямой контроль над зависимостями. Это легко – обнаружить Control Freak: каждое место, когда вы используете ключевое слово new (в C #, по крайней мере), чтобы создать экземпляр изменчивой зависимости, вы являетесь Control Freak, и не имеет значения, сколько слоев фабрик вы используете, чтобы скрыть этот факт. Единственное место, где можно использовать ключевое слово new для зависимостей, это Composition Root.

Избавиться от Control Freak – это наиболее важная задача на сегодняшний день. Только тогда, когда вам удалось отсеять экземпляры Control Freak, вам стоит обратить внимание на другие анти-паттерны: они гораздо менее разрушительные.

Совет

Control Freak мешает вам использовать слабую связанность, другие же DI анти-паттерны просто делают использование неудобным, поэтому я сразу акцентирую ваше внимание на Control Freak.

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

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

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

Service Locator может выглядеть привлекательно, но я считаю его анти-паттерном, хотя это несколько спорное мнение. Несмотря на то, что он решает некоторые проблемы DI, он вводит другие проблемы, которые перевешивают его преимущества. Нет никаких причин принимать его недостатки, поскольку DI паттерны, представленные в главе 4, предлагают лучшие альтернативы. Это общая тема для всех анти-паттернов, описанных в этой главе: DI паттерны из главы 4 предлагают решения проблем, вызванных анти-паттернами.

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