В «идеальном» CQRS ваше агрегатное состояние должно содержать все, что необходимо для выполнения команд, и вы не должны общаться с другими агрегатами во время выполнения команд (потому что они находятся за пределами согласованности)
Итак, бизнес-правилопроверки (решение о том, можете ли вы выполнить данную команду) должны идти в обработчик команд агрегата.
Правила форматирования команды (обязательные поля, допустимые значения) следует проверять перед отправкой команды - на клиенте и перед передачейкоманда в обработчик команд (поскольку мы не можем полностью доверять клиенту).
Поэтому я бы оставил правила проверки формата команд где-то ближе к определению команды - возможно, в декларативной форме, а не в качестве выделенного валидатора.
В некоторых случаях агрегат не может полностью проверить правильность команды без запроса состояния других агрегатов.Вот хорошая статья о межагрегатной связи .Короче говоря, вы не должны общаться с другими агрегатами во время выполнения команды.
Классический пример - создание пользователя с уникальным именем.Похоже, что сообщество считает, что:
вы проверяете имя пользователя как уникальное на клиенте - перед отправкой команды.
Агрегирование пользователей выполняеткоманда без проверки на уникальность.
Те редкие случаи, когда кто-то зарегистрировал одно и то же имя пользователя непосредственно перед отправкой команды, попадают в код проекции и вызывают исключение, которое разрешается вручную.Или есть какая-то сага, которая бы следила за дублированными именами пользователей и как-то справлялась бы с этими проблемами.
Итак - валидация бизнес-правил, которые требуют, чтобы межагрегатное взаимодействие было лучше помещено в Saga / ProcessМенеджер