Совокупные корни ссылаются на другие совокупные корни - PullRequest
27 голосов
/ 07 февраля 2011

В настоящее время я много работаю с DDD и сталкиваюсь с проблемой при загрузке / работе с корнями агрегата из других корней агрегата.

Для каждого корня агрегата в моей модели у меня такжерепозиторий.Хранилище отвечает за обработку постоянных операций для корня.

Допустим, у меня есть два агрегатных корня с некоторыми членами (сущностями и объектами значений).

AggregateRoot1 и AggregateRoot2.

AggregateRoot1 имеет член сущности, который ссылается на AggregateRoot2.

  1. Когда я загружаю AggregateRoot1, должен ли я также загружать AggregateRoot2?
  2. Должно ли хранилище для AggregateRoot2 отвечать за это?
  3. Если так, можно лисущность в AggregateRoot1 для вызова хранилища AggregateRoot2 для загрузки?

Кроме того, когда я создаю связь между сущностью в AggregateRoot1 и AggregateRoot2, это должно быть сделано через сущность или через хранилище дляAggregateRoot2?

Надеюсь, мой вопрос имеет смысл.

[РЕДАКТИРОВАТЬ]

ТЕКУЩЕЕ РЕШЕНИЕ

Ссправка от Twith2Sugars Я пришел к следующему решению:

Как описано в вопросе, у совокупного корня могут быть дети, которые hAve ссылки на другие корни.При назначении 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)
    }
}

Это простой пример, без законаДеметры или других лучших принципов / методов включены: -)

Дополнительные комментарии приветствуются.

Ответы [ 2 ]

59 голосов
/ 07 февраля 2011

Я сам был в этой ситуации и пришел к выводу, что слишком много болит голова, чтобы заставить детские агрегаты работать элегантно.Вместо этого я бы подумал, нужно ли вам ссылаться на второй агрегат как на дочерний по отношению к первому.Это значительно упрощает жизнь, если вы просто сохраняете ссылку на идентификатор агрегата, а не на сам агрегат.Затем, если существует логика домена, которая включает оба агрегата, ее можно извлечь в службу домена и выглядеть примерно так:

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);
    }
}

РЕДАКТИРОВАНИЕ:

I ДЕЙСТВИТЕЛЬНО рекомендую эти статьи на эту тему: https://vaughnvernon.co/?p=838

0 голосов
/ 07 февраля 2011

Возможно, хранилище AggregateRoot1 может вызывать хранилище AggregateRoot2 при создании сущности AggregateRoot1.

Я не думаю, что это делает недействительным DDD, так как хранилища все еще отвечают за получение / создание своих собственных сущностей.

...