Зависимости лука в архитектуре на одном уровне: инфраструктура и веб-коммуникация
Я разрабатываю приложение ASP.NET MVC с использованием Onion Architecture, описанной Джеффри Палермо.
Это проект ASP.NET MVC 2.0, где я требую строгой типизации всех представлений с использованием выделенных моделей представлений - мы не будем передавать доменные модели нашим представлениям. Для перевода мы используем AutoMapper - AutoMapper изолирован в инфраструктуре, Web не знает и не заботится об использовании AutoMapper.
В настоящее время я определяю интерфейсы IViewModelMapping в веб-проекте - просто потому, что эта служба будет использоваться контроллерами и имеет прямой доступ к своим собственным моделям представления. Таким образом, интерфейс может получить доступ как к моделям домена (в ядре), так и к моделям просмотра (в сети).
Чтобы обеспечить фактическую реализацию интерфейсов IViewModelMapping, я создал пространство имен ObjectMapping в проекте инфраструктуры, который изолирует фактическую реализацию отображения от внутренней структуры лука. При этом для этого потребуется, чтобы инфраструктура зависела от ОБА ЯДРО И Web.
У меня вопрос: поскольку оба эти проекта технически находятся на окраине лука (в одном и том же слое) - разрешено ли одному проекту зависеть от другого проекта в этом слое? Кто-нибудь замечает какие-либо потенциальные подводные камни с этим дизайном?
Альтернативным дизайном будет перемещение интерфейсов IViewMapper в Core, но это будет невозможно, поскольку у Core нет доступа к классам ViewModel. Я также мог бы переместить модели представления в Core, но я чувствую, что они не будут там принадлежать, поскольку они специфичны для уровня пользовательского интерфейса.
Предлагаемая архитектура выглядит следующим образом: обратите внимание, что инфраструктура зависит от Core AND Web. Сеть остается изолированной и имеет доступ только к основной бизнес-логике.
3 ответа
Вы правы в том, что не хотите, чтобы инфраструктура зависела от пользовательского интерфейса (Web), но я иногда нарушаю это правило.
Я думаю, что вместо IViewModelMapping создайте IMapper с помощью метода Map(). Тогда интерфейс может иметь реализации, которые могут иметь отношение к отображению модели представления или, может быть, просто к обычному отображению. В любом случае, этот интерфейс может быть в Core, поскольку он не связан семантически с каким-либо типом модели.
Отличная графика. Я надеюсь, что ответил на суть вашего вопроса. Общая философия Onion Architecture состоит в том, чтобы держать вашу бизнес-логику и модель в середине (ядро) вашего приложения и выдвигать ваши зависимости как можно дальше.
Ваш уровень Web/UI может зависеть от уровня инфраструктуры. Но не очень хорошо иметь зависимость Web от слоя Infrastructure. Архитектура луковиц говорит о том, что ваши зависимости должны быть как можно дальше.
Вы можете создать папку "\Builder" в пользовательском интерфейсе. Добавьте в него один интерфейсный файл, например. IBuilder или IMapper и объявите в нем метод типа ConvertToViewModel или CreateMapping. что угодно.
* Builder ** IBuilder.cs - здесь описывается метод. **Builder.cs - реализуйте здесь метод, определите отображение между ViewModel и его соответствующим DomainModel(ссылка из основного уровня) и верните соответствующий ViewModel здесь.