Подтвердить что ты не робот

Разрешение зависимостей в архитектуре лука

Theion Architecture - это способ структурирования приложений для поддержания разделения внимания и ослабления связи (пример проекта: http://onionarch.codeplex.com/). Инъекция/разрешение зависимостей является ключевым аспектом этой архитектуры, поскольку она используется для связывания всех слоев вместе.

В приведенной выше ссылке содержится пример приложения о том, как структурировать ASP.NET MVC с использованием лукового слоя. Мне это очень нравится, но в большинстве этих примеров используется Ninject (который, как мы все знаем, довольно медленный). Мне было интересно узнать, может ли кто-нибудь помочь в интеграции другого инструмента DI (например, SimpleInjector, Unity или Autofac) в проект Onion.

Ключевым моментом является то, что все слои имеют только 1 зависимость (включая проект MVC), а именно уровень ядра. За исключением уровня разрешения зависимостей, этот слой может ссылаться на все слои.

Мне сложно установить проект MVC в качестве проекта запуска, используя DI, и не включая ссылку на инструмент DI в слое MVC.

4b9b3361

Ответ 1

Ваш вопрос

", как интегрировать другой инструмент DI (например, SimpleInjector, Unity или Autofac) в проект лука?"

Im, используя StructureMap вместо Ninject, способ его интеграции должен быть одобрен для любой другой среды DI.

Как вы сказали, только уровень разрешающей способности должен ссылаться на все остальные слои, это самый внешний слой вашей луковой архитектуры. Ну, для этого Ive создал проект под названием BootStrapper. Это единственный проект, в котором я ссылаюсь на сборки StructureMap. В папке App_Start этого проекта у меня есть файл StructureMapMvc.cs, который выглядит так:

[assembly: WebActivator.PreApplicationStartMethod(typeof(XXXX.BootStrapper.App_Start.StructuremapMvc), "Start")]

namespace XXXX.BootStrapper.App_Start
{
    public static class StructuremapMvc
    {
        public static void Start()
        {
            IContainer container = IoC.Initialize();
            System.Web.Mvc.DependencyResolver.SetResolver(new StructureMapDependencyResolver(container));
            GlobalConfiguration.Configuration.DependencyResolver = new StructureMapHttpDependencyResolver(container);
            ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory());
        }
    }
}

Интересная строка:

[assembly: WebActivator.PreApplicationStartMethod(typeof(XXXX.BootStrapper.App_Start.StructuremapMvc), "Start")]

В соответствии с описанием пакетов самородок:

WebActivator - это пакет NuGet, который позволяет другим пакетам выполнять некоторый код запуска в веб-приложениях.

Довольно круто, да? Последнее, что вам нужно сделать, это убедиться, что сборка проекта BootStrapper будет перенесена в папку /bin вашего веб-приложения (легко настраивается с помощью действия post build или OutputTo nugget пакет). Это позволит вам ссылаться на проект BootStrapper в вашем проекте MVC и нарушить принцип Onion Architecture.

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

Надеюсь, это поможет!

Ответ 2

Обратите внимание, что я думаю, что архитектура Onion (или, по крайней мере, пример реализации, на который вы указали, так как @MystereMan правильно указал в комментариях) имеет проблемное место, о котором вы должны знать.

Несмотря на то, что архитектура, похоже, предпочитает небольшие/сфокусированные интерфейсы (часто с одним членом), назначение этих служб, по-видимому, указывает на другое. Например, в ссылочной архитектуре существует класс IShippingService. У этого есть один член, и поэтому он придерживается принципа Принцип разделения села (что хорошо). Однако имя "служба доставки" указывает, что оно должно содержать все методы, связанные с доставкой. Это легко будет десятки. Однако добавление элементов в этот интерфейс нарушает принцип разделения интерфейса, принцип единой ответственности (SRP) и Принцип открытого закрытия (OCP). Реализация станет большой и уродливой с множеством методов с небольшими отношениями или без них (SRP). Реализация нового требования к доставке означает добавление члена, и это нарушает OCP. Интерфейс имеет много членов, в то время как потребителям часто приходится только звонить одному из этих членов (низкая сплоченность), и это будет более сложным.

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

Является ли это проблемой или нет, зависит от множества факторов, но нарушение одного из принципов SOLID всегда что-то следить.

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