domain-driven-design - DDD : one aggregate root , 多个持久数据源

标签 domain-driven-design persistence microservices ddd-repositories aggregateroot

在指南/电子书中:.NET Microservices: Architecture for Containerized .NET Applications (与 eShopOnContainers 相关)“设计基础设施持久层”(第 213 页)一章中一般性地解释了聚合根如何针对持久数据源执行 CUD 操作。

提到了两个重要的起点:

  1. 聚合不了解持久性方法和基础设施,遵循“持久性无知”和“基础设施无知”原则(第 218 页)。聚合由业务而不是基础设施决定。
  2. 每个聚合根只能定义一个存储库,以维护聚合内对象之间的事务一致性(第 213 页)

不幸的是,在提到的所有其他示例中,聚合根和属于它的所有底层对象都位于同一个持久数据源中。

模式如下:

  1. 创建一个包含该聚合的存储库
  2. 在此存储库中,在创建过程中会注入(inject)一个工作单元。此工作单元包含 SaveChangesAsync、SaveEntitiesAsync、Update 等方法 等等。
  3. 在命令中,工作单元管理事务以 这是一个数据源,例如数据库或类似的数据源。

我想扩展这种模式,即聚合可以根据底层对象类型将其数据写入 2 个或更多物理数据源。

从起点 1 开始,完全有理由根据底层对象的类型将根聚合及其底层对象更新到不同的数据源。提到的示例有:数据库和 XML 文件、数据库和 NOSQL“数据库”、数据库和服务、数据库和 IoT 设备。因为聚合必须不了解持久性和基础设施的方法,所以我认为没有必要争论聚合的设计。我认为书中没有提到聚合根应该保留在一个数据源中。

同时,出发点 2 似乎也完全合理。因为聚合根中的完整对象集已被编辑,并且整个包的成功持久性是从一个存储库和(最好)从一个工作单元协调的。

问题是: 如果在聚合中(取决于底层对象的类型)它在不同的数据源上进行水合,那么如何处理领域驱动设计? 我是否应该使用一个自定义工作单元并决定在该 UoW 中写入何处?

我知道下一个question ,但研究了 code我认为它只处理处理不同数据源的存储库的继承,但当时仍然为一个数据源提供服务,而这不是我所追求的。

最佳答案

I want to expand this pattern that the aggregate can write its data over 2 or more physical data sources depending on the underlying object type.

你为什么要故意这么做?

在大多数情况下,选择持久性实现来服务域,而不是相反。因此,幸福的道路通常涉及选择一个可以记录整个聚合状态的持久性解决方案,并将整个事物存储在单个事务中。

因此,如果您发现自己尝试将聚合存储在两个不同的位置,则应该仔细研究原因。

一个常见的答案是您希望能够有效地查询聚合状态。 是一种常见的解决方案 - 不是将聚合持久保存在两个不同的数据存储中,而是将其持久保存到一个数据存储中并将其复制到另一个数据存储中。查询可以针对副本非常高效地运行(尽管在聚合更改和查询结果中反射(reflect)该更改之间当然存在一些额外的延迟)。

另一个常见的答案是,您确实有两个相互引用的聚合。将两个聚合存储在不同的地方并没有什么问题。在代码中明确区分两者可能会更好。

How deals Domain Driven Design if within the aggregate - depending on the type of the underlying object - it is hydrated over different data sources?

糟糕的是,就像其他人一样。

关于domain-driven-design - DDD : one aggregate root , 多个持久数据源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49100994/

相关文章:

hibernate 一对一: AnnotationException Referenced property not a (One|Many)ToOne

java - 有没有办法保持与静态 Web 服务的连接?

c# - 洋葱架构 : Core vs Domain

domain-driven-design - 实体可以访问存储库吗?

entity - 持久性无知如何与(非根)聚合的引用一起工作?

spring - 如何将 TDD 应用于逐层封装设计?

storage - NiFi如何将流数据存储在内存或磁盘中

kubernetes - EKS 工作节点可以设置在不同的区域吗

java - 如何在 Spring Boot 中使用特定日期范围和聚合从 MongoDB 数据库检索数据?

c# - DDD 封装和存储库模式