在 eShopOnContainers 中的 DDD 微服务中应用 CQRS 和 CQS 方法

小窍门

此内容摘自电子书《适用于容器化 .NET 应用程序的 .NET 微服务体系结构》,可以在 .NET Docs 上获取,也可以下载免费的 PDF 以供离线阅读。

适用于容器化 .NET 应用程序的 .NET 微服务体系结构电子书封面缩略图。

eShopOnContainers 参考应用程序的订购微服务的设计基于 CQRS 原则。 但是,它使用最简单的方法,该方法只是将查询与命令分离,并将同一数据库用于这两个作。

这些模式的本质及其要点是查询是幂等的:无论查询系统多少次,系统的状态都不会改变。 换而言之,查询没有副作用。

因此,即使排序微服务使用相同的数据库,也可以使用与事务逻辑“写入”域模型不同的“读取”数据模型。 因此,这是一种简化的 CQRS 方法。

另一方面,触发事务和数据更新的命令在系统中更改状态。 使用命令时,需要小心处理复杂性和不断变化的业务规则。 这是你想要应用 DDD 技术以建立更好的建模系统的位置。

本指南中介绍的 DDD 模式不应普遍应用。 它们引入了对设计的约束。 这些约束提供了好处,例如随着时间的推移质量更高,尤其是在命令和修改系统状态的其他代码中。 但是,这些约束增加了复杂性,读取和查询数据的好处更少。

其中一种模式是“聚合”模式,我们将在后面的部分中进行更多检查。 简言之,在“聚合”模式中,将许多域对象视为一个单元,因为它们在域中的关系。 在查询中,可能并不总是从此模式中获得优势;它可以增加查询逻辑的复杂性。 对于只读查询,无法获取将多个对象视为单个聚合的优势。 而只会增加复杂性。

如上一部分中图 7-2 所示,本指南建议仅在微服务的事务/更新区域中使用 DDD 模式(即命令触发)。 查询可以采用更简单的方式,并在CQRS架构中与命令分离。

若要实现“查询端”,可以从完整的 ORM(如 EF Core)、AutoMapper 投影、存储过程、视图、具体化视图或微 ORM 等许多方法中进行选择。

在本指南和 eShopOnContainers(特别是订购微服务)中,我们选择使用类似于 Dapper 的微 ORM 实现直接查询。 本指南使你能够基于 SQL 语句实现任何查询,以获得最佳性能,这要归功于一个开销很小的精简框架。

使用此方法时,如果对模型进行任何更新,且该更新会影响实体持久保存到 SQL 数据库的方式,那么同时需要 对 Dapper 使用的或任何其他单独的查询方法(非 EF)使用的 SQL 查询进行单独更新。

CQRS 和 DDD 模式不是顶级体系结构

请务必了解,CQRS 和大多数 DDD 模式(如具有聚合的 DDD 层或域模型)不是体系结构样式,而只是体系结构模式。 微服务、SOA 和事件驱动的体系结构(EDA)是体系结构样式的示例。 它们描述许多组件的系统,例如许多微服务。 CQRS 和 DDD 模式描述单个系统或组件内的内容;在本例中,微服务内的内容。

不同的界定上下文 (BC) 采用不同的模式。 他们有不同的责任,这会导致不同的解决方案。 值得强调的是,在任何地方强制采用相同的模式会导致失败。 不要随处使用 CQRS 和 DDD 模式。 许多子系统、DC 或微服务更简单,可以使用简单的 CRUD 服务或使用其他方法更轻松地实现。

只有一个应用程序体系结构:要设计的系统或端到端应用程序的体系结构(例如微服务体系结构)。 但是,该应用程序内每个边界上下文或微服务的设计反映了它在体系结构模式级别上自己的权衡和内部设计决策。 不要尝试在任何地方应用与 CQRS 或 DDD 相同的体系结构模式。

其他资源