C# 如果存储库用于聚合根,那么其他实体的数据访问逻辑应该放在哪里?

C# 如果存储库用于聚合根,那么其他实体的数据访问逻辑应该放在哪里?,c#,.net,domain-driven-design,C#,.net,Domain Driven Design,我有几个表示web应用程序的对象。目前,我有一个集群对象来表示应用程序的特定部署。在集群对象中,我有以下对象:服务器、客户、用户。这些对象中没有一个不属于集群的,所以我创建了一个ClusterRepository来从数据库中检索集群。现在,我需要从集群中获得一个客户列表,大概是通过使用集群对象中的一个方法,比如GetCustomers()。现在,我最初的想法是将此操作的工作转移到CustomerRepository,但由于存储库仅用于聚合根,数据访问逻辑应该去哪里?这是否属于服务类?本质上,聚合

我有几个表示web应用程序的对象。目前,我有一个集群对象来表示应用程序的特定部署。在集群对象中,我有以下对象:服务器、客户、用户。这些对象中没有一个不属于集群的,所以我创建了一个ClusterRepository来从数据库中检索集群。现在,我需要从集群中获得一个客户列表,大概是通过使用集群对象中的一个方法,比如GetCustomers()。现在,我最初的想法是将此操作的工作转移到CustomerRepository,但由于存储库仅用于聚合根,数据访问逻辑应该去哪里?这是否属于服务类?

本质上,聚合根是您可能需要获取作为对象图根的任何对象。仅仅因为一个特定实体是聚合根,并且有一个存储库,并不意味着作为其属性之一的另一个实体也不能是聚合根,因为它有自己的存储库

一个很好的例子是客户计费系统。客户肯定是聚合根,并将包含发票集合。。。但对于另一个应用程序函数,发票本身可能是一个聚合根,其对象图中包含组成LineItem对象

因此,在您的示例中,如果在某些情况下需要独立于集群获取客户,那么为客户创建另一个存储库并没有错


注意:请参见注释中的线程。尽管根实体可以(而且通常会)引用其他根实体,但不赞成(这一说法可能过于温和)允许任何根实体的存储库包含管理(创建、更新或删除)其对象图中有引用的任何根实体的功能。任何此类被引用的根实体都应该有自己的单独存储库,并且管理它们的功能(创建、更新和/或删除操作)应该在它们的存储库中,以便它只在一个位置

聚合根是负责其包含的所有实体的生命周期的对象。聚合根的存在是为了维护有效的关系不变量,因此获取访问权不是创建聚合根的原因。这个答案似乎表明,根据调用方的角度,会产生一个聚合根。发票要么是聚合根目录,要么不是。时期对于最初的问题,如果客户被视为聚合根,集群仍然可以有一个引用,但客户现在不再是集群聚合根的一部分。如果我正确理解您的反对意见,这等同于要求定义的聚合集中没有重叠,这将是不寻常和不必要的。关于根据应用程序域的访问要求建立聚合的另一点,我引用Evans的话,“……仅为实际需要直接访问的聚合根提供存储库……”当然,通常情况下,作为一个聚合的一部分的实体可能需要直接访问,包括其组成部分,在application.Evans p124的另一部分中,“聚合是一个关联对象的集群,我们将其视为数据更改的一个单元。”根是负责控制对聚合中所有其他对象的更改/访问的对象。我反对的是一个实体,它有时是一个聚合的非根部分,有时是它自己聚合的根。实体可以作为第一个聚合的成员删除,之后它将无法控制自己的聚合。根不能是另一个聚合的一部分,因为它负责将自己的聚合保持在有效状态。我怀疑您不理解这个概念。从DDD的第129页,Evans清楚地说“聚合中的对象可以包含对其他聚合根的引用”。分离点在根部。聚合根可以是其他聚合的一部分,事实上,如果不允许,就没有合理的方法来设计系统。当重叠包含多个聚合边界中的非根对象时,该范例不赞成。这被认为是不好的,因为多个聚合可能会不一致地修改这些对象。但是这个范例必须允许根对象的重叠。你把引用和聚合的“成员”混淆了。研究汽车的例子。Car是聚合根,在其聚合中有实体。引擎也是一个聚合根。汽车有一个引擎的参考,但引擎从来不是汽车集合的一部分。根据同样的论点,如果根重叠,一个根可以修改另一个根。如果mod是一个delete,那么第二个root可以将其负责的实体孤立。更糟糕的矛盾。在Evans中,您将找不到作为聚合根的对象同时也是另一个聚合成员的示例。