Должны ли модели предметной области вызывать инфраструктурные интерфейсы?

является ли следующий хороший дизайн и допустимым в луковой архитектуре и дизайне, управляемом доменом?

скажем, у вас есть класс домена «Заказ», например

class Order
{
  INotificationService _notificationService;
  ICartRepository _cartRepository;

   void Checkout(Cart cart, bool notifyCustomer)
   {
         _cartRepository.Save(cart);
         if (notifyCustomer)
         {
            _notificationService.sendnotification();
         }
   }
}

Хорошо или плохо иметь интерфейсы вызова модели домена инфраструктуры? (в данном случае это служба уведомлений и CartRepository)


person user2309367    schedule 22.11.2013    source источник
comment
Вы уверены, что вызов уведомления клиента касается вашего Заказа? Это, скорее, кажется мне проблемой уровня приложения. Как насчет будущих действий, которые необходимо выполнить, когда покупатель оформляет заказ, таких как предоставление кредита на будущие продажи, уведомление вашей внутренней базы данных статистики, другая бухгалтерия и т. д.? Вы всегда собираетесь изменять класс Order? Для принципов SPR я предлагаю создать событие домена, как в ответах ниже, и обработать событие в независимых наблюдателях.   -  person Alexander Langer    schedule 29.11.2013


Ответы (4)


Ваш проект будет в порядке только в том случае, если интерфейсы INotificationService и ICartRepository определены в вашем слое Domain (Core) и если они связаны во время выполнения с правильной реализацией вашим слоем Dependency Resolution (самым внешним слоем вашего Луковая архитектура).

Помните, что в луковой архитектуре ваш слой Domain не может ссылаться ни на какие библиотеки.

Реализация ICartRepository, очевидно, будет выполняться на вашем уровне Infrastucture, поскольку она наверняка будет привязана к вашей технологии уровня доступа к данным.
Если вашей реализации INotificationService нужно взаимодействовать с внешней службой, она также переходит на Infrasrtructure. Но если это часть вашего бизнеса, то ее реализация может быть на уровне Domain.

person MaxSC    schedule 25.11.2013

Я думаю, что INotificationService — это концепция предметной области, а не инфраструктурная служба. Мы могли бы смоделировать это как событие DomainEvent, сообщающее «покупатель о корзине сохранен».

Как насчет перемещения INotificationService на уровень домена и переименования его в «CartDomainEvents».

CartDomainEvents.raise(CartSavedEvent(...));

В общем случае компоненты инфраструктуры вызовов вводят двунаправленные зависимости, что обычно не является хорошей схемой.

person Yugang Zhou    schedule 23.11.2013
comment
"Calling infrastructure components introduces bidirectional dependencies which is usually not a good design". Вы определенно правы, но помните, что в луковой архитектуре все зависимости направлены к центру! Так что двунаправленные зависимости ни в коем случае нельзя допускать! - person MaxSC; 25.11.2013

Уровень репозитория существует для каждого агрегата домена, репозиторий находится поверх домена, вы можете иметь базовые интерфейсы репозитория в своем домене, которые находятся в инфраструктуре, но вы не можете видеть реализации репозитория в своей модели (это неправильно). есть некоторые базовые интерфейсы, такие как UnitOfWrok, Repository, аутентификация Specificationm и ... в вашей инфраструктуре, доступные на всех уровнях. Я рекомендую взглянуть на витрину магазина aghata, написанную на .net, чтобы увидеть реальный проект реализации https://github.com/elbandit/Asp-Net-Design-Patterns-CQRS

person Ehsan    schedule 11.12.2013

репозиторий относится к уровню инфраструктуры, также было бы лучше использовать интерфейс Icart

void Checkout(ICart cart, bool notifyCustomer)

для уменьшения сцепления.

person Arash    schedule 20.02.2015