CQRS命令和查询 - 它们属于域吗?

Sam*_*Sam 31 domain-driven-design cqrs

在CQRS中,它们的命令和查询是否属于域?

事件是否也属于域?

如果是这种情况,那么命令/查询处理程序只是在基础架构中实现吗?

现在我有这样的布局:

Application.Common
Application.Domain
  - Model
    - Aggregate
  - Commands
  - Queries
Application.Infrastructure
  - Command/Query Handlers
  - ...
Application.WebApi
  - Controllers that utilize Commands and Queries
Run Code Online (Sandbox Code Playgroud)

另一个问题,你从哪里筹集事件?命令处理程序或域聚合?

Tom*_*uλa 46

命令事件可能有很多不同的问题.它们可能是技术问题,集成问题,域名问题......

我假设如果您询问域名,那么您将实施域模型(甚至可能使用域驱动设计).

如果是这种情况,我会尝试给你一个非常简化的回复,所以你可以有一个起点:

  • 命令:是一种商业意图,是您希望系统执行的操作.保持域中命令的定义.从技术上讲,它只是一个纯粹的DTO.命令的名称应始终是命令式" PlaceOrder "," ApplyDiscount "一个命令仅由一个命令处理程序处理,如果无效则可以丢弃(但是在将命令发送到域之前应该进行所有验证)它不能失败)
  • 事件:这是过去发生的事情.对于企业而言,这是不可改变的事实.将域事件的定义保留在域中.技术上它也是一个DTO对象.但是,事件的名称应始终位于过去的" OrderPlaced "," DiscountApplied "中.事件通常是pub/sub.一个出版商许多处理程序.

如果是这种情况,那么命令/查询处理程序只是在基础架构中实现吗?

命令处理程序在语义上类似于应用程序服务层.通常,应用程序服务层负责编排域.它通常围绕业务用例构建,例如"下订单".在这些用例中,通过聚合根,查询等来调用业务逻辑(应始终封装在域中).它也是处理交叉问题(如事务,验证,安全性等)的好地方.

但是,应用程序层不是必需的.它取决于功能和技术要求以及已经制定的架构选择.你的发言似乎是正确的.我最好将命令处理程序保留在系统的边界.如果没有合适的应用程序层,命令处理程序可以扮演用例orchestrator的角色.如果将其放在域中,您将无法轻松处理横切问题.这是一个权衡.您应该了解解决方案的利弊.它可能在一个案例中有效而在另一个案例中有效.

至于事件处理程序.我一般都在处理它

  • 应用程序层,如果事件触发在同一有界上下文中修改另一个聚合,或者该事件触发某些基础结构服务.
  • 如果事件需要拆分为多个使用者或集成其他有界上下文,则为基础结构层.

无论如何,你不应该盲目遵守规则.总是存在权衡,可以找到不同的方法.

另一个问题,你从哪里筹集事件?命令处理程序或域聚合?

我是从域聚合根目录进行的.因为域负责引发事件.由于始终存在技术规则,如果在聚合中持续存在更改的问题,则不应发布事件,反之亦然,我采用事件采购中使用的方法,这是务实的.我的聚合根有一组Unpublished事件.在我的存储库的实现中,我将检查集合Unpublished事件并将它们传递给负责发布事件的中间件.如果持有聚合根的异常,则很容易控制,不会发布事件.有人说这不是存储库的责任,我同意,但是谁在乎.什么是选择.使用所有基础架构问题(事务,异常处理等)进入事件发布的尴尬代码,或者实用并处理Infrastructure层中的所有内容?我已经做到了,相信我,我更喜欢务实.

总而言之,没有一种做事方式.始终了解您的业务需求和技术要求(可扩展性,性能等).而不是基于此做出选择.我已经描述了我在大多数情况下所做的一般工作.这只是我的意见.

  • 存储库保留了AR.但是命令处理程序调用存储库.关于发布事件,我不会从存储库中发布它们,它不是真正的责任.我也不同意命令/查询处理程序是基础结构的一部分.如果你这样做,那么几乎每个域用例和每个查询都是基础结构的一部分.您最终得到了一个庞大的基础架构和一个只有概念而没有进程/用例的域. (3认同)

gui*_*e31 9

在一些实现中,命令和处理程序位于应用程序层中. 其他人中,他们属于域名.我经常在OO系统中看到前者,后者更多地在功能实现中看到,这也是我自己做的,但是YMMV.

如果您通过事件表示域事件,那么......是的,我建议在域层中定义它们并从域对象中发出它们.域事件是您无处不在的语言的重要组成部分,如果您练习事件风暴,甚至可以由领域专家直接创建,因此将它们放在那里绝对是有意义的.

我认为你应该记住的是,对于大多数这些技术细节都没有规则,这些细节值得一成不变.关于DDD模板项目以及SO上的分层和代码"地形"有无数的问题,但坦率地说,我认为这些问题在制作强大,高性能和可维护的应用程序时不具有决定性作用,特别是因为它们与上下文有关.您很可能不会为每分钟有数百万次汇总更改的交易系统组织代码,就像50人使用博客发布平台一样,即使两者都采用DDD方法设计.有时你必须根据你的背景为自己尝试一些事情,并一路学习.