DDD,BoundedContexts,域事件和事务

时间:2011-05-31 17:21:40

标签: domain-driven-design ddd-repositories

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

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

产品系统(内部部署)
BaseProduct(定义香草产品)
ResellerProduct(定义将由经销商销售的基础产品的定制) CustomerProduct(定义客户注册的产品)。

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

我首先将这些区域划分为两个不同的有界背景,派对和产品。我为这些上下文中的每一个定义了域模型,并且在实体中引用了另一个模型中的概念,我将这些概念留作简单的Guid ID(即产品域中的CustomerProduct将具有相关Guid的CustomerRef值)。

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

例如:

  • ApplicationService.RegisterNewProduct(客户ID, 产品编号)
  • 开始每个单位的交易 工作(PartyUnitOfWork.Begin(), ProductUnitOfWork.Begin())
  • 为每个上下文使用存储库 找到相关的域对象 (Party.Customer.Find(ID) Product.ResellerProduct.Find(Id)的)
  • 执行逻辑以确定是否 客户有资格,产品是 有效等。
  • 创建一个新的CustomerProduct并保存 到产品系统
  • 提交每个上下文UnitOfWork

然后我开始进一步探索有限的上下文,并考虑重构应用程序,以便每个上下文具有来自另一个的概念的有限表示,但仅特定于该上下文。即在产品上下文中,我将有一个客户实体,它具有Id,Name和活动状态但可能不是联系首选项等。然后,我将使用DomainEvents来协调不同系统之间的活动,以使其数据保持最新(即如果在CRM系统中创建了一个新客户,产品系统将引发并处理一个事件,以更新其客户的表示。因此,上述示例将发生变化,因此仅使用了Product上下文。

为了进一步混淆问题,请说'RegisterNewProduct'调用还创建了一个新客户,我是否会在产品系统中创建客户并提出一个由Party系统处理的'NewCustomer'事件?

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

1 个答案:

答案 0 :(得分:1)

除了我的评论/问题,您描述的UnitOfWork方法存在根本问题。你会遇到其中一个承诺的单位和一个失败的问题。您将最终得到跨越两个上下文的分布式事务。

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

如果您是纯粹主义者,则可以将此方法用于所有聚合间通信。通过这样做,您可以完全取消拥有工作单元的要求。

它有意义吗?