.NET IoC: предварительная настройка компонентов библиотеки для более легкого использования
Некоторое время назад у меня был похожий вопрос, но с гораздо меньшим пониманием всей темы IoC/DI, а также того, чего я стремился достичь, так что здесь снова...
Я строю библиотеку для общего пользования в нашей компании. Наиболее часто используемые части общедоступного API-интерфейса уже совместимы с IoC, но в областях более низкого уровня все еще происходят некоторые нововведения, от которых я бы хотел избавиться (хотя в настоящее время это больше по формальным причинам, чем по-настоящему). необходимость).
Само по себе это будет достаточно легко сделать, но, конечно, каждый раз, когда библиотека используется, все компоненты должны быть снова подключены. Поскольку это будет выглядеть почти всегда одинаково, я обычно просто обертываю эти регистрации по умолчанию в модуле Autofac и покончу с этим.
(Вот вопрос 1. Будет ли этот модуль помещаться в основную сборку библиотеки или это будет автономный пакет, даже если Autofac, вероятно, будет единственным контейнером IoC, используемым с библиотекой?)
Теперь проблема в том, что я на данный момент являюсь единственным разработчиком в компании, который действительно видит цель IoC или знает, что вообще делает контейнер IoC, не говоря уже о том, как он используется, и было бы плохой идеей рассказать всем остальным, что они можете использовать пакет Autofac или просто построить график из дюжины объектов + вручную, используя DI для бедного человека. (Я знаю ребят - они просто оставили бы это в покое и сами построили бы то, что им нужно, потому что я в любом случае схожу с ума от всех моих крошечных уроков.)
Я решил решить эту проблему, добавив что-то вроде сервисного локатора, из которого можно извлекать предварительно сконфигурированные объекты для часто используемых типов (которые будут выглядеть так же, как те, что подключены модулем Autofac), возможно, внутренне подключенный с помощью легкого контейнера IoC.,
Я знаю, что Service Locator является антипаттерном и какие виды проблем он создает, и я бы никогда не использовал его в качестве (моего) средства для компоновки объектов, но в качестве "ярлыка" для IoC/SOLID с нарушениями, было бы возможно? Какие еще варианты у меня будут? Может ли в этом случае иметь смысл включать модуль Autofac в библиотеку и просто использовать "Сервисный локатор" в качестве внешнего интерфейса для него?
1 ответ
Для каркаса действуют другие правила, чем для бизнес-приложений. Это справедливо, на мой взгляд, и при применении внедрения зависимостей. Вы видите это, глядя на дизайн корпоративной библиотеки Microsoft Patterns & Practices. Он полностью разработан на основе шаблона внедрения зависимостей, но обычные пользователи не будут этого знать. Он использует фабрики, чтобы облегчить жизнь пользователя. В вашем случае нецелесообразно заставлять других разработчиков использовать внедрение зависимостей, поскольку это, вероятно, только раздражает их, поскольку вы делаете вещи, которые только кажутся усложняющими, и они не увидят выгоды от этого. Это, вероятно, вызовет у них негативное чувство в целом с DI, и вы потеряете возможность познакомить их с DI позже (потому что они уже примут во внимание его неприязнь).
Будет ли этот модуль находиться в основной сборке библиотеки или это будет отдельный пакет?
Обычно я бы не интегрировал это в саму библиотеку, поскольку с архитектурной точки зрения вы просто не хотите, чтобы ваша библиотека зависела от какого-либо DI-контейнера. Однако, если вы посмотрите на Enterprise Library, вы увидите, что она сильно зависит от инфраструктуры Unity DI. Вы можете изменить EntLib, чтобы использовать другой контейнер, но EntLib все еще ссылается на Unity. Это позволило разработчикам каркаса предоставлять пользователю удобные фабричные методы, и это позволяет использовать каркас, не вызывая какой-либо метод Framework.Bootstrap в вашем приложении.
Сделайте все возможное, чтобы спроектировать свою среду с учетом принципов SOLID, потому что вы знаете, что это просто лучшее, что нужно сделать. Это также позволяет продемонстрировать этот способ проектирования приложений в будущем (и может заинтересовать других в внедрении зависимостей). Но, как разработчик фреймворка, вы должны подумать о том, кто ваши пользователи, и придумать API, который им подходит. Помните, например, о рекомендациях по разработке структуры для.NET.
Глядя на Enterprise Library, вы видите, что у корневых / основных типов есть фабрика. Все остальное разрешено для вас под одеялом. Я думаю, что это путь. Не беспокойте своих пользователей API-интерфейсом, где они должны сами все связывать, особенно для обычных / простых случаев использования.