【问题标题】:DDD : one aggregate root , multiple persistent datasourcesDDD:一个聚合根,多个持久数据源
【发布时间】:2018-08-12 13:11:17
【问题描述】:

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

提到了两个重要的起点:

  1. 聚合不知道遵循 Persistence Ignorance 和 Infrastructure Ignorance 原则(第 218 页)的持久性方法和基础架构。聚合由业务而非基础架构决定。
  2. 应该只为每个聚合根定义一个存储库,以保持聚合内对象之间的事务一致性(第 213 页)

不幸的是,在所有进一步提到的示例中,聚合根及其下的所有底层对象都在同一个持久数据源中。

那么模式如下:

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

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

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

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

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

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

【问题讨论】:

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


    【解决方案1】:

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

    你为什么要故意这样做?

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

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

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

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

    如果在聚合中(取决于底层对象的类型)如何处理领域驱动设计,它通过不同的数据源进行水合?

    很糟糕,就像其他人一样。

    【讨论】:

    • 这个答案是我希望避免的:在我的设计中,我必须考虑持久性的方法(在某些情况下)。在这些情况下,域服务于持久性解决方案,而不是相反。
    猜你喜欢
    • 2014-08-11
    • 2011-02-07
    • 1970-01-01
    • 1970-01-01
    • 2015-12-02
    • 2015-01-04
    • 2020-03-20
    • 1970-01-01
    • 2016-03-29
    相关资源
    最近更新 更多