Агрегатный корень ссылается на другие совокупные корни
В настоящее время я много работаю с DDD, и я столкнулся с проблемой при загрузке/работе с помощью Aggregate корней из других корней совокупности.
Foreach Совокупный корень в моей модели, у меня также есть репозиторий. Теперь репозиторий отвечает за обработку операций с постоянным доступом для корня.
Предположим, что у меня есть два Aggregate Roots, с некоторыми членами (объектами и объектами Value).
AggregateRoot1 и AggregateRoot2
AggregateRoot1 имеет член сущности, который ссылается на AggregateRoot2
- Когда я загружаю AggregateRoot1, должен ли я также загружать aggregateRoot2?
- Это репозиторий для aggregateRoot2, который должен нести ответственность за это.
- Это так, нормально ли сущность в aggregateRoot1 вызывать репозиторий aggregateRoot2 для загрузки?
Кроме того, когда я создаю связь между объектом в AggregateRoot1 с AggregateRoot2, это должно быть сделано через объект или через репозиторий для aggregateRoot2.
Надеюсь, мой вопрос имеет смысл.
[EDIT]
ТЕКУЩЕЕ РЕШЕНИЕ
С помощью 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)
}
}
Это просто простой пример: ни один закон Деметры или другие лучшие принципы/практики не включали: -)
Другие комментарии оценены
Ответы
Ответ 1
Возможно, репозиторий AggregateRoot1 может вызвать репозиторий AggregateRoot2 при создании объекта AggregateRoot1.
Я не думаю, что это делает недействительным ddd, поскольку репозитории по-прежнему отвечают за получение/создание своих собственных объектов.
Ответ 2
Я был в этой ситуации сам и пришел к выводу, что слишком много боли в голове, чтобы заставить дочерние агрегаты работать элегантно. Вместо этого я бы подумал, нужно ли вообще ссылаться на второй агрегат как на ребенка первого. Это облегчает жизнь, если вы просто сохраняете ссылку на совокупный идентификатор, а не на фактический агрегат. Затем, если есть логика домена, которая включает в себя оба агрегата, это можно извлечь в службу домена и выглядеть примерно так:
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);
}
}
EDIT:
I ДЕЙСТВИТЕЛЬНО рекомендую эти статьи по теме: https://vaughnvernon.co/?p=838