Я разрабатываю свои агрегаты для обеспечения соблюдения инвариантов и бизнес-правил. Я всегда рассматриваю свой агрегат как «модель записи» / «модель транзакции».
Учитывая это, я всегда могу свободно показывать «сложные» методы GET в своих репозиториях, используя пользовательский SQL / Linq, потому что я не изменяю данные.
Например, рассмотрим два фиктивных совокупных корня (ученик и школа), используя только ссылочные идентификаторы между ними. Если я хочу отправить электронное письмо всем учащимся школы, я обычно использую службу домена, которая выполняет это, для повышения производительности:
- Вызывает репозиторий с помощью метода, подобного «GetAllStudentEmailAddressesForSchool (Guid schoolId)»
- Отправляет электронное письмо каждому ученику
Конечно, реализация репозитория должна была бы выполнить «сложный» запрос (JOIN) для двух агрегатов.
Типичной альтернативой может быть организация нескольких вызовов в репозитории в доменной службе:
- Выбрать школу из репозитория ISchool
- Foreach StudentId Школы, позвоните в IStudentRepository
(Конечно, это зависит от совокупного моделирования, но основная концепция остается).
У меня было много споров с коллегами по этому поводу, многие утверждают, что первый подход пропускает бизнес домена вне домена (он же на уровне инфраструктуры, в реализации репозитория).
Для меня это простая стратегия фильтрации, аналогично тому, как ISchoolRepository представляет такой метод, как «GetSchoolsFromCity (Guid cityId)». Тот факт, что фильтрация выполняется для одного агрегата вместо двух, ничего не меняет.
Есть мнения по этому поводу?