如何为这个领域驱动的设计挑战建模?

How to model this domain driven design challenge?

在这里学习 DDD。

有两种用户Members和Staff。会员可以拥有订阅列表,并且可以随时购买额外的订阅。员工用户还可以向成员添加订阅。员工用户在会员系统中添加订阅时,应该记住是谁添加了这个订阅。

会员和员工用户处于完全不同的有界上下文中。他们拥有不同的权利,可以参加不同的小组。因此,我创建了一个成员聚合根,其中包含单独的有界上下文 "Member" 中的订阅列表。然后我在单独的有界上下文 Staff 中创建了 Staff 聚合根。

当会员想要购买额外的订阅时,这很容易,MemberService 只需将新订阅附加到会员,因为订阅是会员聚合和会员限界上下文的一部分。

但是,当员工用户想要向用户添加新订阅时,问题就开始了,因为不再是会员自己购买订阅,而是员工将订阅分配给会员。

我在这里看到了多个解决方案,但其中 none 个似乎完全正确。

  1. 将订阅实体添加到员工聚合。 (尴尬,因为员工没有订阅)
  2. 当员工用户添加订阅时,引发一个事件,通过成员聚合向成员添加成员订阅。 (尴尬,因为不是会员加订阅)
  3. 直接从staff service调用member aggregate(违反DDD原则)。
  4. 将 Subscription 移动到其自身的限界上下文中,并使其成为聚合根。 (这是错误的,因为成员与 his/her 订阅关系密切)

我在这里错过了什么?

子问题:

是否允许在多个限界上下文服务中使用相同的 DTO?

据我了解,您确实至少有两个限界上下文,但不是(仅?)您确定的那些:Subscriptions bounded contextAuthorization bounded context

Subscriptions bounded context 包含成员获得新订阅或取消现有订阅时使用的逻辑。规则是这样的:一个会员可以拥有他想要的任意数量的订阅。其他人可以添加订阅。

Authorization bounded context 包含 user 可以向成员添加订阅的规则。如果用户是会员,则他只能向他的会员帐户添加订阅。如果用户来自员工,那么他可以向其他成员添加订阅,但不能向自己的成员添加订阅,除非他也是成员(第一条规则)。

有两个限界上下文,你需要整合它们。在用例 "adding a subscription to a member" 中使用了两个限界上下文。您可以通过先从 Authorization bounded context 调用 query/domain 服务来在应用程序服务中实现这一点,以检查当前经过身份验证的用户是否可以向成员添加订阅。如果他不能,则 return 异常情况下加载 MemberSubscriptions 聚合,调用 addSubscription(subscriptionId, idIfTheUserThatAddsTheSubscription, subscriptionType, etc...) 然后将聚合保存在存储库中。

请注意,应用程序服务未实例化新的 Subscription 实体,这是 MemberSubscriptions 聚合的工作,您必须保护其封装。您甚至可以将 Subscription 实体 class 保持为私有(受保护、包或您在 C# 中拥有的任何语言机制)。无论如何,对成员订阅 的任何访问都必须 MemberSubscriptions 聚合根(如 addSubscriptionremoveSubscriptionhasSubscription 等完成).