Domain driven design DDD、BoundedContext、域事件和事务
我目前正在根据DDD原则为产品/政党管理系统创建概念验证。其中一项要求是,第三方数据(客户、经销商)将存储在web上的CRM中,特定于产品的数据将存储在本地SQL数据库中(见下文) CRM系统(基于Web)Domain driven design DDD、BoundedContext、域事件和事务,domain-driven-design,ddd-repositories,Domain Driven Design,Ddd Repositories,我目前正在根据DDD原则为产品/政党管理系统创建概念验证。其中一项要求是,第三方数据(客户、经销商)将存储在web上的CRM中,特定于产品的数据将存储在本地SQL数据库中(见下文) CRM系统(基于Web) 客户(包括姓名、地址、电子邮件、联系人偏好等) 经销商(包含名称、地址、活动状态) 产品系统(内部部署) 基本产品(定义香草产品) 转销商产品(定义转销商将销售的基础产品的定制) CustomerProduct(定义客户注册的产品) 我一直在对如何实现解决方案的不同方法进行大量研究,但我很难
客户(包括姓名、地址、电子邮件、联系人偏好等)
经销商(包含名称、地址、活动状态) 产品系统(内部部署)
基本产品(定义香草产品)
转销商产品(定义转销商将销售的基础产品的定制) CustomerProduct(定义客户注册的产品) 我一直在对如何实现解决方案的不同方法进行大量研究,但我很难理解所有概念以及它们如何应用于我的问题 我首先将这些区域划分为两个不同的有界上下文:Party和Product。我为这些上下文中的每一个定义了域模型,其中实体引用了另一个模型中的概念,我将这些作为简单的Guid ID(即产品域中的CustomerProduct将具有相关Guid的CustomerRef值) 然后,我实现了一个使用API调用web CRM的Party基础设施实现和一个使用NHibernate的产品基础设施实现。对于其中的每一个,我都实现了一个UnitOfWork,这样我就可以在每个上下文中控制事务流程。应用层将在运行时注入这两个上下文并使用它们 例如:
- ApplicationService.RegisterNewProduct(customerId, ProductId)
- 启动每一个交易单元的交易 工作(PartyUnitOfWork.Begin(), ProductUnitOfWork.Begin())
- 为每个上下文使用存储库 查找相关的域对象 (一方客户查找(Id), 产品.经销商产品.查找(Id))
- 执行逻辑以确定 客户合格,产品合格 有效等
- 创建新的CustomerProduct并保存 产品体系
- 提交每个工作单元
我有兴趣收集人们对这些想法的评论?除了我的评论/问题之外,您所描述的UnitOfWork方法还有一个根本问题。您将遇到一系列问题,其中一个单元已提交,另一个单元已失败。您将最终得到一个跨两个上下文的分布式事务 如果您确实需要多个有界上下文,则更好的(主观)方法是在它们之间进行异步、基于消息的通信。您在一个上下文中对聚合执行命令,并在将更改持久化到数据库的同一事务中发布(例如,通过NServiceBus或MassTransit)发生了某事的消息(事件)。另一个上下文接收消息/事件并作出反应 如果你是一个纯粹主义者,你可以将这种方法用于所有聚合间的通信。通过这样做,你可以完全消除拥有一个工作单元的要求
这有什么意义吗?除了我的评论/问题之外,您所描述的UnitOfWork方法还有一个根本问题。您将遇到一系列问题,其中一个单元已提交,另一个单元已失败。您将得到一个跨两个上下文的分布式事务 如果您确实需要多个有界上下文,则更好的(主观)方法是在它们之间进行异步、基于消息的通信。您在一个上下文中对聚合执行命令,并在将更改持久化到数据库的同一事务中发布(例如,通过NServiceBus或MassTransit)发生了某事的消息(事件)。另一个上下文接收消息/事件并作出反应 如果你是一个纯粹主义者,你可以将这种方法用于所有聚合间的通信。通过这样做,你可以完全消除拥有一个工作单元的要求
这有意义吗?为什么需要两个概念?在这些上下文中是否有不同含义的术语?如果没有歧义,我会从一个简单的上下文开始,然后将其拆分,如果其大小无法管理。理想情况下,我只需要一个上下文,即一个客户拥有一组CustomerProducts。但是,因为e在这种情况下,客户和客户产品将在不同的系统中,我认为他们需要分开。因此,我将有一个持久层与CRM实体交互,另一个与数据库实体交互。我不确定我将如何构建它,否则,我将有一个持久层可以d通过NHibernate处理对CRM和数据库的访问?我认为如何存储和检索数据是一个技术细节,您应该将此逻辑深入到存储库实现中。为什么d