聚合根引用其他聚合根

tsc*_*uck 27 domain-driven-design aggregate loading repository aggregateroot

我目前正在使用DDD工作很多,并且在从其他聚合根加载/操作聚合根时遇到问题.

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

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

AggregateRoot1和AggregateRoot2.

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

  1. 当我加载AggregateRoot1时,我是否应该加载AggregateRoot2?
  2. AggregateRoot2的存储库是否应对此负责?
  3. 如果是这样,AggregateRoot1中的实体是否可以调用AggregateRoot2的存储库进行加载?

此外,当我在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)
    }
}
Run Code Online (Sandbox Code Playgroud)

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

进一步评论赞赏.

Dav*_*ers 59

我自己一直处于这种状况,并得出结论认为让孩子聚合体以优雅的方式工作太过头痛.相反,我会考虑你是否真的需要引用第二个聚合作为第一个聚合的孩子.如果你只是保留聚合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);
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:

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

  • + 1. 这也是 Vaughn Vernon 在他的“通过同一性引用其他聚合”规则中所主张的。优点包括整体聚合大小导致更好的性能和更容易的分区。我猜的缺点是它有时会降低模型代码的表现力,所以它像往常一样进行权衡:http://dddcommunity.org/sites/default/files/pdf_articles/Vernon_2011_2.pdf (2认同)

TWi*_*ars -5

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

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