聚合根引用其他聚合根

时间:2011-02-07 09:28:04

标签: domain-driven-design repository aggregate loading aggregateroot

我目前正在使用DDD进行大量工作,并且在从其他聚合根加载/操作聚合根时遇到问题。

对于我模型中的每个聚合根,我也有一个存储库。存储库负责处理根的持久性操作。

假设我有两个聚合根,包含一些成员(实体和值对象)。

AggregateRoot1和AggregateRoot2。

AggregateRoot1有一个引用AggregateRoot2的实体成员。

  1. 当我加载AggregateRoot1时,我是否应该加载AggregateRoot2?
  2. AggregateRoot2的存储库是否应对此负责?
  3. 如果是这样,AggregateRoot1中的实体是否可以调用AggregateRoot2的存储库进行加载?
  4. 此外,当我在AggregateRoot1中的实体与AggregateRoot2之间创建关联时,是应该通过实体还是通过AggregateRoot2的存储库来完成?

    希望我的问题有道理。

    [编辑]

    当前解决方案

    Twith2Sugars的帮助下,我提出了以下解决方案:

    如问题所述,聚合根可以有子引用其他根。将root2分配给root1的其中一个成员时,root1的存储库将负责检测此更改,并将其委托给root2的存储库。

    public void SomeMethod()
    {
        AggregateRoot1 root1 = AggregateRoot1Repository.GetById("someIdentification");
        root1.EntityMember1.AggregateRoot2 = new AggregateRoot2();
        AggregateRoot1Repository.Update(root1);
    }
    
    public class AggregateRoot1Repository
    {
        public static void Update(AggregateRoot1 root1)
        {
            //Implement some mechanism to detect changes to referenced roots
            AggregateRoot2Repository.HandleReference(root1.EntityMember1, root1.EntityMember1.AggregateRoot2)
        }
    }
    

    这只是一个简单的例子,不包括Demeter法或其他最佳原则/实践: - )

    进一步评论赞赏。

3 个答案:

答案 0 :(得分:57)

我自己一直处于这种状况,并且得出的结论是,让孩子聚合以优雅的方式工作太过头痛。相反,我会考虑你是否真的需要引用第二个聚合作为第一个聚合的孩子。如果你只是保留聚合ID的引用而不是实际的聚合本身,那么它会让生活变得更加容易。然后,如果存在涉及两个聚合的域逻辑,则可以将其提取到域服务并看起来像这样:

public class DomainService
{
    private readonly IAggregate1Repository _aggregate1Repository;
    private readonly IAggregate2Repository _aggregate2Repository;

    public void DoSomething(Guid aggregateID)
    {
        Aggregate1 agg1 = _aggregate1Repository.Get(aggregateID);
        Aggregate2 agg2 = _aggregate2Repository.Get(agg1.Aggregate2ID);

        agg1.DoSomething(agg2);
    }
}

修改

真的推荐这些主题的文章:https://vaughnvernon.co/?p=838

答案 1 :(得分:0)

此方法存在一些问题。首先,您应该为每个聚合及其完成建立一个存储库。具有一个可以调用另一个存储库的存储库违反了此规则。其次,关于聚合关系的一个好习惯是,一个根聚合应通过其ID与另一个根聚合通信,而不要使用其引用。这样,您可以使每个聚合独立于另一个聚合。仅在组成相同聚合的类的根聚合中保留引用。

答案 2 :(得分:-4)

也许AggregateRoot1存储库在构建AggregateRoot1实体时可以调用AggregateRoot2存储库。

我认为这不会使ddd无效,因为存储库仍然负责获取/创建自己的实体。