1

我目前正在根据 DDD 的原则为产品/政党管理系统创建概念证明。其中一项要求是各方数据(客户、经销商)将存储在网络上的 CRM 中,而产品特定数据将存储在本地 SQL 数据库中(见下文)。

CRM 系统(基于 Web)
客户(包含姓名、地址、电子邮件、联系方式等)
经销商(包含姓名、地址、活动状态)

产品系统(本地)
BaseProduct(定义普通产品)
ResellerProduct(定义将由经销商销售的基本产品的定制) CustomerProduct(定义客户注册的产品)。

我一直在对如何实施解决方案的不同方法进行大量研究,但我正在努力理解所有概念以及它们如何应用于我的问题。

我首先将这些区域分成 2 个不同的有界上下文,Party 和 Product。我为这些上下文中的每一个定义了域模型,并且在其他模型中实体引用了概念时,我将它们保留为简单的 Guid Id(即产品域中的 CustomerProduct 将具有相关 Guid 的 CustomerRef 值)。

然后,我实现了一个使用对 Web CRM 的 API 调用的 Party 基础架构实现和一个使用 NHibernate 的 Product 基础架构实现。对于其中的每一个,我都实现了一个 UnitOfWork,这样我就可以控制每个上下文中的事务过程。应用层将在运行时注入两个上下文并使用它们。

例如:

  • ApplicationService.RegisterNewProduct(customerId, ProductId)
  • 启动每个工作单元的事务(PartyUnitOfWork.Begin()、ProductUnitOfWork.Begin())
  • 使用每个上下文的存储库来查找相关的域对象(Party.Customer.Find(Id)、Product.ResellerProduct.Find(Id))
  • 执行逻辑以确定客户是否符合条件、产品是否有效等。
  • 创建一个新的 CustomerProduct 并保存到产品系统
  • 提交每个上下文 UnitOfWork

然后,我开始进一步探索有界上下文,并考虑重构应用程序,以便每个上下文对另一个上下文的概念表示有限,但仅特定于该上下文。即在产品上下文中,我将有一个客户实体,它有一个 ID、名称和活动状态,但可能没有联系偏好等。然后我将使用 DomainEvents 来协调不同系统之间的活动,以保持他们的数据是最新的(即,如果在 CRM 系统中创建了一个新客户,一个事件将由产品系统引发和处理,以更新其客户代表)。因此上面的例子会改变,所以只使用了 Product 上下文。

为了进一步混淆问题,假设“RegisterNewProduct”调用也创建了一个新客户,我是否会在产品系统中创建客户并引发将由 Party 系统处理的“NewCustomer”事件?

我有兴趣收集人们对这些想法的评论吗?

4

1 回答 1

1

除了我的评论/问题之外,您描述的 UnitOfWork 方法存在根本问题。你会遇到一整类问题,其中一个单元已提交,一个单元失败。您最终将得到一个跨越两个上下文的分布式事务。

如果您确实需要多个有界上下文,则更好的(主观)方法是在它们之间进行基于消息的异步通信。您在一个上下文中针对聚合执行命令,并且在将更改持久化到数据库的同一事务中,您发布(例如通过 NServiceBus 或 MassTransit)发生某事的消息(事件)。另一个上下文接收消息/事件并做出反应。

如果您是一个纯粹主义者,您可以使用这种方法进行所有聚合间的通信。通过这样做,您可以完全消除拥有工作单元的要求。

这有什么意义吗?

于 2011-06-02T06:42:18.520 回答