How/where 在 DDD 和基于 CQRS/ES 的系统中加载不同 BC 中的实体值对象

How/where to load value object that is entity in different BC in DDD and CQRS/ES based system

我已经学习了这个很棒的教程:http://www.cqrs.nu/tutorial/cs/01-design 并尝试以同样的方式制作我的应用程序。

根据我之前的问题我知道,一个 BC 中的实体是什么可以表示为包含另一个 BC 中的实体标识符和可选的任何其他参数的值对象。 (我把这些标识符放到了 Core BC 中。)

现在,假设我有两个 BC:PlansEditorSubscribing

PlansEditor 中,假设有 Editor(有角色的人),当他使用 frequencyvip 等参数创建 Plan 时,然后创建 Plan

Subscribing 中,假设有 Customer 和一些可用的 Plan,当客户订阅 Plan 时,就会创建 Subscription

这里的计划可能只是带有频率和 VIP 参数的 VO,因为订阅只需要它们(以保护不变量)。但是客户点击订阅计划并发送带有计划 ID 的请求。

因此,我以客户 ID 和他订阅的计划 ID 开始我的 BC 生命周期。我需要通过某处给定的标识符 load/create Plan "value object"(这实际上是 PlansEditor BC 中的实体)。

我应该在哪里以及如何在 Subscribing BC 获得该计划 VO?

我想在应用层通过事件存储库 - 能够发送包含此值对象的 SubscribeCustomerToPlanCommand(Customer, Plan)。但是 Subscribing BC 然后需要知道 Plan 作为 PlansEditor 中的实体存在,以便加载它并将其转换为 Plan 作为 VO,这是不可接受的 - 一个 BC需要其他才能正常运行。

或者我应该只从一些读取模型中获取创建 Plan VO 所需的信息,然后在应用程序层执行此操作,这样方便吗?或者如何以及在哪里? :)

据我所知,Plan 在这两种情况下都不是 VO。并不是因为一个 BC 对实体的生命周期具有权威,实体在其他上下文中成为 VO(它可以)。

如果下游上下文需要了解远程上下文中实体的生命周期,那么该实体也应该建模为下游上下文中的实体。

例如,我想 Plans 可以在某个时候停用,允许订阅这些是没有意义的?这将是一个很好的指标,表明 Plan 订阅 上下文中不是一个简单的值。

在 BC 集成方面有多种策略,但如果您更喜欢可用性而不是一致性,那么消息传递很可能是更好的选择。上游上下文将在消息传递基础结构上发布事件,这些事件将被下游上下文使用,从而使其保持实体状态的本地副本同步。

"BC would then need to know that Plan as entity in PlansEditor exists in order to load it and translate it to Plan as VO, which is unacceptable - one BC would need other to function properly"

任何集成策略都需要一定程度的耦合,但这种耦合应该在反腐败层中抽象出来。