В приведенном вами примере PairAssetsCommand
не может быть обработан одним AssetAggregate
, поскольку он охватывает границу согласованности двух отдельных агрегатных экземпляров. А именно, два разных AssetAggregate
s.
Обратите внимание, что Aggregate определяет границу согласованности в вашей модели команд. Таким образом, любая принятая ею команда и все ее результирующие события (и последующие изменения состояния) будут рассматриваться как операция atomi c. Создание ассоциаций между несколькими сущностями через это может означать две вещи:
- Вы создаете больший совокупный класс, охватывающий все
AssetAggregate
с. - У вас есть Внешний обработчик команд (т. Е.
@CommandHandler
вне агрегата), который обрабатывает PairAssetsCommand
.
. Я бы посоветовал отказаться от первого варианта, так как он увеличит согласованность ограничить весь набор активов в вашей системе. В конечном итоге это станет главным узким местом для требования Агрегата о «сохранении границы согласованности».
Таким образом, остается вариант 2. Давайте перефразируем бизнес-логику c, которую вы определили:
если оба актива не сопряжены, тогда выполните их сопряжение (измените статус на сопряженный и добавьте UUID в relatedAssets), в противном случае создайте исключение
Это означает, что вы не можете проверить один экземпляр, но нужно сделать это на нескольких. Опять же, вы можете пойти двумя путями, чтобы решить эту проблему:
- Отправьте
AssociateWithAssetCommand
обоим AssetAggregate
и отправьте компенсационную команду, если один из AssetAggregate
уже связан. - Используйте набор на основе проверки во внешнем обработчике команд, обрабатывающем
PairAssetsCommand
, для проверки вашей бизнес-логики c.
Какой из двух вариантов лучше оставь на предпочтение скажу. Решение второе требует, чтобы у вас была небольшая модель запроса, содержащая набор активов и их статус ассоциации ». Кроме того, эту модель запроса необходимо обновить в в той же транзакции , что и при выполнении команд ассоциации. Таким образом, несколько сложнее.
Следовательно, решение 1 будет самым простым способом go в вашем сценарии.