Получение всех совокупных дочерних сущностей корневых сущностей?

Я пытаюсь реорганизовать свое приложение из репозитория для каждой сущности в репозиторий для каждого совокупного корня.

Базовый пример: у меня есть корень сущности Cars. У автомобилей есть договоры аренды. Насколько я понимаю, контракты не существуют без автомобилей, поэтому автомобили - это совокупный корень.

Я пытаюсь реализовать пользовательское представление, которое будет отображать каждый контракт в системе (все дочерние сущности корневых сущностей). Перед рефакторингом я мог просто зайти в свой репозиторий контрактов и получить All. Поскольку репозиторий контрактов был удален (поскольку он не является корневым), мне теперь нужно вытащить все машины из моего репозитория, а затем получить все их контракты.

У моего репозитория есть интерфейс

public interface ICarRepository
{
    IQueryable<Car> All { get; }
    IQueryable<Car> AllIncluding(params Expression<Func<Car, object>>[] includeProperties);
    Car Find(long id);
    void InsertOrUpdate(Car car);
    void Delete(long id);
    void Save();
}

Я подумал о создании ICarManagementService и о том, чтобы у него был метод GetAllContracts (возможно, с параметрами фильтра). Означает ли это, что мне нужно получить все контракты, вытащить все автомобильные объекты со своими контрактами, а затем извлечь все объекты, связанные с контрактами на аренду, и отфильтровать их?

Затем я могу передать их контроллеру и автоматически сопоставить контракты, как и раньше.

Это лучшая практика?

Спасибо

Грэм


person GraemeMiller    schedule 18.09.2011    source источник


Ответы (2)


Насколько я понимаю, контракты не существуют без автомобилей, поэтому автомобили - это совокупный корень.

Это не обязательно правда. «Не существовать без» недостаточно для того, чтобы объект стал частью агрегированного корня. Рассмотрим классическую область обработки заказов. У вас есть заказ, который является совокупным корнем. У вас также есть клиент, который является совокупным корнем. Заказ не может существовать без Клиента, но это не означает, что Заказы являются частью Агрегата Клиентов. В объектах DDD внутри одного агрегата могут быть ссылки на другие агрегированные корни. Из книги DDD:

Объекты внутри AGGREGATE могут содержать ссылки на другие корни AGGREGATE.

Агрегат - это жизненный цикл и единица обмена данными. По сути, это кластер объектов, обеспечивающий инварианты. Это то, что вы хотите заблокировать, если у вас есть несколько пользователей, меняющих домен одновременно.

Возвращаясь к вашему вопросу, я понимаю, что домен - это что-то вроде аренды / аренды автомобиля / грузовика / лимузина / бульдозера. Я думаю, что HireContract не может быть частью агрегата Car, потому что у них могут быть разные жизненные циклы, а HireContract имеет смысл сам по себе, без автомобиля. Кажется, что это больше похоже на отношения «заказ-продукт», которые также являются классическим примером того, как два разных агрегата ссылаются друг на друга. Эта теория подтверждается еще и тем, что бизнесу необходимо видеть «Все контракты». Они, вероятно, не думают о машине, содержащей все контракты. Если это правда, вам нужно сохранить свой ContractsRepository.

В другой заметке, вам может быть интересно прочитать этот ответ об интерфейсе репозитория. дизайн.

person Dmitry    schedule 18.09.2011
comment
Я действительно думал, что хочу, чтобы люди могли блокировать автомобили для редактирования. Я могу рассматривать контракты по найму как совокупность. Мне нужно, чтобы люди не добавляли перекрывающиеся периоды найма. Могу ли я добиться этого, если набор сотрудников является совокупным. - person GraemeMiller; 18.09.2011
comment
Трудно ответить на этот вопрос, не разбираясь в своей области. Но я могу вам намекнуть. Уди Дахан и / или Грег Янг упомянули метод, в котором вы должны попытаться представить, как эта функция будет реализована в «бумажном» бизнесе без компьютеров. Это может привести к более асинхронному подходу (разрешая временное перекрытие периодов найма, например, Amazon позволяет двум клиентам заказывать книгу, даже если на складе остается только 1, а затем уведомляет вас по электронной почте). Многого можно добиться, если удалить все, что должно быть на 100% согласовано все время. - person Dmitry; 20.09.2011
comment
Возможно, позже опубликую более подробный вопрос. Мой экземпляр синей книги должен прибыть на этой неделе, так что, надеюсь, я получу лучшее представление о хорошей практике DDD. Спасибо за помощь. - person GraemeMiller; 21.09.2011

Отделите концепцию чтения / запроса от записи / команды, поскольку в соответствии с CQRS предпочтительнее разрабатывать приложение, разделяя модель чтения, которая состоит из запросов только для чтения, и модель записи, с другой стороны, которая состоит из команд для выполнения определенной логики. на модели предметной области.

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

если вы обнаружите, что хотите запросить коллекцию объектов, чтобы выполнить некоторую логику домена, тогда это индикатор того, что вам нужно абстрагировать эту коллекцию и поместить ее в совокупный корень, чтобы инкапсулировать их и заставить бизнес-операцию или метод воздействовать на них .

проверить (http://moh-abed.com/2011/09/13/pure-old-ddd-with-a-twist-from-cqrs/) и (http://simon-says-architecture.com/ 2011/08/23 / репозиторий)

person Mohamed Abed    schedule 18.09.2011
comment
Эти ссылки мертвы, хорошо бы процитировать важные части в ответе. К счастью, старые снимки находятся в https://web.archive.org/web/20150531070309/http://moh-abed.com/2011/09/13/pure-old-ddd-with-a-twist-from-cqrs/ и https://web.archive.org/web/20160403195814/http://simon-says-architecture.com/2011/08/23/repository/ - person kravemir; 16.01.2021
comment
Однако это хороший ответ. Совокупные корни DDD на самом деле связаны только с областью выполнения / изменения команды ... Но существуют разные проблемы просмотра только для чтения, когда нет смысла рассматривать агрегированные корни, например агрегировать запросы для статистики, отчетов, элементов панели ... - person kravemir; 16.01.2021