У меня вопрос по DDD и шаблону репозитория.
Скажем, у меня есть репозиторий клиентов для совокупного корня клиентов. Методы Get и Find возвращают полностью заполненный агрегат, который включает такие объекты, как Address и т. Д. Все в порядке. Но когда пользователь ищет клиента в пользовательском интерфейсе, мне просто требуется «сводка» совокупности - просто плоский объект с обобщенной информацией.
Один из способов, которым я мог бы справиться с этим, - это вызвать метод find в репозитории как обычно, а затем на уровне приложения сопоставить каждую совокупность клиентов с CustomerSearchResult / CustomerInfo DTO и отправить их обратно клиенту.
Но моя проблема с этим - производительность; для каждой совокупности клиентов может потребоваться несколько запросов для заполнения всех ассоциаций. Так что, если мои критерии поиска соответствуют 50 клиентам, это большой удар для БД, поскольку потенциально я могу получить данные, которые мне даже не понадобятся.
Другая проблема заключается в том, что я могу включить обобщенные данные о клиенте, который находится за пределами совокупной корневой границы клиента, например, дату последнего сделанного заказа. Заказ имеет свой собственный агрегат, и поэтому для получения информации о заказе клиента мне пришлось бы вызвать OrderRepository, что также ухудшило производительность.
Итак, теперь я думаю, что у меня осталось два варианта:
Добавьте в CustomerRepository дополнительный метод Find, который возвращает список этих итоговых объектов, выполняя один эффективный запрос.
Создайте специально созданный CustomerInfoRepository только для чтения, в котором есть только метод поиска, описанный в 1.
Но в обоих случаях кажется, что я иду против принципов DDD. Мои репозитории наследуются от общей базы: Репозиторий, где T: IAggregateRoot. Эти объекты сводной информации не являются агрегатами и относятся к типу, отличному от T, поэтому на самом деле № 1 идет вразрез с дизайном.
Возможно, для №2 я бы создал абстрактный SearchRepository без ограничения IAggregateRoot?
В моей сфере много подобных сценариев.
Как бы вы реализовали этот сценарий?
Спасибо, Дэйв
Обновить
Прочитав ответ Тео, я думаю, что выберу вариант № 2 и создам в своей инфраструктуре специализированный SearchRepository, ориентированный на эти сценарии. Затем прикладной уровень (службы WCF) может вызывать эти репозитории, которые просто заполняют сводные DTO напрямую, а не сопоставляют сущности домена с DTO.
**** Обновление 2 ****
Хотя я спросил об этом больше года назад, я подумал, что просто добавлю, что с тех пор я обнаружил CQRS, который нацелен на решение именно этой проблемы. Уди Дахан (http://www.udidahan.com/) и Грег Янг (http://codebetter.com/gregyoung/) много писали об этом. Если вы создаете распределенное приложение с DDD, CQRS для вас!