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

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

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

Марк Симан

15.5. Резюме

Среди всех остальных DI-контейнеров, охваченных в части 4, MEF является самым особенным. Во-первых, это единственная технология компоновки, официально поставляемая и поддерживаемая компанией Microsoft. Во-вторых, MEF, в действительности, является не DI-контейнером, а фреймворком расширяемости (как видно из его названия Managed Extensibility Framework), поэтому рассматривать его с той позиции, как если бы он был DI-контейнером, было бы не правильно.

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

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

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

Имеет ли смысл использовать в приложениях MEF в качестве DI-контейнера? Ответ на этот вопрос зависит от обстоятельств. Одним из сильных аргументов в пользу использования MEF является тот факт, что MEF является частью .NET 4 и Silverlight 4, поэтому если для приложения будут использоваться эти платформы, MEF в них уже будет доступен. Дело не только в удобстве применения. Для тех организаций, в которых согласно их внутренней политике должны использоваться только официальные технологии компании Microsoft, использование MEF может стать большим преимуществом.

Поскольку MEF – это официальный продукт компании Microsoft, нам предоставляется другой уровень поддержки, нежели тот, который мы получали при использовании других DI-контейнеров. Нам предоставляется такая же поддержка, как и при использовании .NET и Silverlight, при этом мы можем быть уверены, что в MEF не возникнет неполадок.

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

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

Неважно, какой DI-контейнер вы выбрали, или даже если вы предпочитаете Poor Man's DI, я надеюсь, что эта книга передала вам следующую мысль: механизм внедрения зависимостей не основывается на какой-то конкретной технологии, например, на конкретном DI-контейнере. Приложения могут и должны создаваться с помощью DI-дружественных паттернов и приемов, описанных в этой книге. Если мы в этом преуспели, то огромное значение имеет выбор DI-контейнера. DI-контейнер – это инструмент, который компонует наше приложение, но в идеале мы должны уметь заменять один контейнер на другой, не переписывая при этом другие части нашего приложения, кроме как Composition Root.