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