Domain driven design CQRS命令和查询-它们是否属于域?
在CQR中,它们的命令和查询是否属于域 这些事件是否也属于该域 如果是这种情况,那么命令/查询处理程序是否只是基础结构中的实现 现在我把它布置成这样:Domain driven design CQRS命令和查询-它们是否属于域?,domain-driven-design,cqrs,Domain Driven Design,Cqrs,在CQR中,它们的命令和查询是否属于域 这些事件是否也属于该域 如果是这种情况,那么命令/查询处理程序是否只是基础结构中的实现 现在我把它布置成这样: Application.Common Application.Domain - Model - Aggregate - Commands - Queries Application.Infrastructure - Command/Query Handlers - ... Application.WebApi -
Application.Common
Application.Domain
- Model
- Aggregate
- Commands
- Queries
Application.Infrastructure
- Command/Query Handlers
- ...
Application.WebApi
- Controllers that utilize Commands and Queries
另一个问题,你从哪里提出事件?命令处理程序或域聚合?命令和事件是DTO。您可以在任何层/组件中使用命令处理程序和查询。一个事件仅仅是一个通知,表明某些事情发生了变化。您可以拥有所有类型的事件:域、应用程序等 事件可以由处理程序和聚合程序生成,具体取决于您。但是,不管它们是在哪里生成的,命令处理程序都应该使用服务总线来发布事件。我更喜欢在聚合根目录中生成域事件 从DDD战略的角度来看,只有业务概念和用例。域事件、命令和处理程序是技术细节。但是,所有域用例通常都作为命令处理程序实现,因此命令处理程序和实现域使用的查询的查询处理程序都应该是域的一部分。用户界面使用的查询可以是用户界面的一部分,依此类推
CQR的要点是至少有2个模型,命令应为域模型本身。但是,您可以有一个专门用于域使用的查询模型,但它仍然是一个读取(简化)模型。将命令模型视为仅用于更新,读取模型仅用于查询。但是,您可以有多个读取模型(由特定层或组件使用),也可以只有一个通用模型(用于所有查询) 命令和事件可能是非常不同的关注点。它们可以是技术问题、集成问题、领域问题 我假设,如果您询问域,您正在实现一个域模型(甚至可能使用域驱动设计) 如果是这种情况,我将尝试给你一个非常简单的回答,这样你就可以有一个起点:
- 命令:是一种业务意图,是您希望系统执行的操作。在域中保留命令的定义。从技术上讲,这只是一个纯粹的DTO。命令的名称应始终为命令式“PlaceOrder”,“ApplyDiscount”一个命令仅由一个命令处理程序处理,如果无效,则可以将其丢弃(但是,在将命令发送到域之前,应进行所有验证,以使其不会失败)
- 事件:这是过去发生的事情。对于企业来说,这是一个不可改变的事实。将域事件的定义保留在域中。从技术上讲,它也是一个DTO对象。但是,事件名称应始终为过去的“OrderPlaced”、“DiscountApplied”。事件通常是发布/订阅的。一个发布者有多个处理程序
- 应用程序层,如果事件触发同一有界上下文中另一个聚合的修改,或者如果事件触发某些基础结构服务
- 如果事件需要拆分为多个使用者或集成其他有界上下文,则为基础结构层
未发布的事件。在我的存储库的实现中,我将检查未发布的
事件的集合,并将它们传递给负责发布事件的中间件。很容易控制,如果有异常持久化聚合根,则不会发布事件。有人说这不是存储库的责任,我也同意,但谁在乎呢。选择是什么。有笨拙的事件发布代码潜入您的领域,涉及所有的基础架构问题(事务、异常处理等),还是务实并在基础架构层处理所有问题?我两者都做过,相信我,我更喜欢务实
总而言之,做事没有单一的方式。始终了解您的业务需求和技术要求(可扩展性、性能等)。而不是基于此做出选择。我已经