Как смоделировать эту сложную задачу проектирования?

Обучение DDD здесь.

Существует два вида пользователей: Члены и Персонал. Участник может иметь список подписок и может приобретать дополнительные подписки в любое время. Пользователь может также добавить подписку на член. Когда штатный пользователь добавляет подписку в систему участника, следует помнить, кто добавил эту подписку.

Члены и сотрудники находятся в совершенно разных ограниченных контекстах. У них разные права и разные группы, которые они могут посещать. Поэтому я создал объединенный корень Member, который содержит список подписок в отдельном ограниченном контексте "Member". Затем я создал корень совокупности персонала в отдельном документе "Ограниченный контекст персонала".

Когда участники хотят приобрести дополнительную подписку, это легко, MemberService просто присоединяет новую подписку к члену, потому что подписка является частью совокупности участников и ограниченного контекста участника.

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

Я вижу несколько решений здесь, но ни одно из них не кажется полностью правильным.

  1. Добавить объект подписки в совокупный состав персонала. (неловко, потому что у сотрудников нет подписок)
  2. Когда пользователь-сотрудник добавляет подписку, инициируйте событие, которое добавляет подписку участника на участника через совокупность участников. (неудобно, потому что это не участник, который добавляет подписку)
  3. Позвоните участнику агрегировать напрямую из службы персонала (нарушает принципы DDD).
  4. Переместите подписку в ограниченном контексте для себя и сделайте ее совокупным корнем. (было бы неправильно, потому что участник тесно связан со своими подписками)

Что мне здесь не хватает?

Под вопрос:

Разрешено ли использовать одни и те же DTO в службах с несколькими ограниченными контекстами?

1 ответ

Решение

Из того, что я понимаю, у вас действительно есть как минимум два ограниченных контекста, но не (только?) Те, которые вы определили Subscriptions bounded context а также Authorization bounded context,

Subscriptions bounded context содержит логику, которая используется, когда участники получают новые подписки или отменяют существующую подписку. Правила таковы: у участника может быть столько подписок, сколько он хочет. Подписка может быть добавлена ​​кем-то другим.

Authorization bounded context содержит правила, по которым user может добавить подписку на участника. Если пользователь является участником, он может добавлять подписки только в свою учетную запись. Если пользователь из персонала, то он может добавлять подписки на других участников, но не на своих, если только он не является участником (первое правило).

Имея два ограниченных контекста, вам необходимо интегрировать их. В случае использования "добавление подписки к члену" используются оба ограниченных контекста. Вы можете реализовать это в службе приложений, вызвав сначала службу запросов / доменов из Authorization bounded context проверить, может ли текущий аутентифицированный пользователь добавить подписку к участнику. Если он не может вернуться после исключения, в противном случае загрузите MemberSubscriptions совокупность, вызов addSubscription(subscriptionId, idIfTheUserThatAddsTheSubscription, subscriptionType, etc...) затем сохраните совокупность в хранилище.

Обратите внимание, что служба приложений не создала новый экземпляр Subscription сущность, это работа MemberSubscriptions агрегат, и вы должны защитить его инкапсуляцию. Вы даже можете сохранить Subscription класс сущности как частный (защищенный, пакетный или любой другой языковой механизм, который есть в C#) В любом случае, любой доступ к подписке членов должен быть сделан из MemberSubscriptions совокупный корень (как addSubscription, removeSubscription, hasSubscription так далее).

Другие вопросы по тегам