CQRS и команда, CommandHandler и совокупная проверка - PullRequest
0 голосов
/ 19 октября 2018

Я делаю первые шаги по внедрению CQRS в новый проект.Следуя подходу CQRS, я использую MediatR в качестве основы для управления своими командами.

Я также использую FluentValidation и ValidationBehavior для реализации проверки команд.Но я изо всех сил пытаюсь определить, где поставить, какую проверку:

  • В команде (используя CommandValidator с FluentValidation)
  • В обработчике команд, как пользовательские проверки
  • В корне агрегата (при вызове операций непосредственно в этом агрегате)

Я хотел бы понять, куда и какую проверку поставить:

  • Проверка поля (длина,формат, обязательный, ...)
  • проверки бизнес-правил, требующие реализации IRepository (например, уникальность, основанная на столбце, но не на первичном ключе)
  • проверки бизнес-правил, которые выполняютне требует реализации IRepository

Поскольку я в настоящее время реализовал это, у меня нет доступа к IRepository реализациям в моих агрегатных корнях.Именно обработчики команд получают этот репозиторий, внедряемый DI, и они выполняют операции в агрегатном корне, но также отвечают за вызовы, например, Сохранить или Добавить, чтобы окончательно обновить базу данных.

1 Ответ

0 голосов
/ 19 октября 2018

В «идеальном» CQRS ваше агрегатное состояние должно содержать все, что необходимо для выполнения команд, и вы не должны общаться с другими агрегатами во время выполнения команд (потому что они находятся за пределами согласованности)

Итак, бизнес-правилопроверки (решение о том, можете ли вы выполнить данную команду) должны идти в обработчик команд агрегата.

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

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

В некоторых случаях агрегат не может полностью проверить правильность команды без запроса состояния других агрегатов.Вот хорошая статья о межагрегатной связи .Короче говоря, вы не должны общаться с другими агрегатами во время выполнения команды.

Классический пример - создание пользователя с уникальным именем.Похоже, что сообщество считает, что:

  • вы проверяете имя пользователя как уникальное на клиенте - перед отправкой команды.

  • Агрегирование пользователей выполняеткоманда без проверки на уникальность.

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

Итак - валидация бизнес-правил, которые требуют, чтобы межагрегатное взаимодействие было лучше помещено в Saga / ProcessМенеджер

...