2014-01-20 3 views
5

Я хочу использовать элементы шаблона CQRS в моем проекте. Интересно, правильно ли я делаю это с командами и событиями. То, что я не уверен, это если событие может вызвать команду. Чтобы лучше показать, что я хочу сделать, я буду использовать диаграмму и пример.CQRS - может EventListener вызвать команду?

Это пример:

Пользователь вызова TripCreateCommand. TripCreateCommandHandler выполняет свою работу и после успеха публикует TripCreatedEvent.

Теперь у нас есть два слушателя TripCreatedEvent (порядок исполнения слушатель не имеет значения)

Первый слушатель (может быть выполнить после второго слушателя):

для каждого пользователя в trip.author.friends вызвать два Command (порядок команд важно)

  1. PublishTripOnUserWallCommand
  2. SendNewTripEmailNotificationCommand
  3. SendNewTripPlatformNotification

Второй слушатель (может быть выполняться до первого слушателя):

  1. PublishTripOnUserSocials

И это образец схема:

enter image description here

ли это хороший способ ? Может EventListener вызвать команду, или, может быть, я должен сделать это другим способом?

ответ

9

Ваш вопрос о Mesage Driven Architecture, который работает вместе, но в остальном не связан с CQRS.

Во всяком случае, ваша диаграмма почти правильная. Абонент/обработчик событий (я предпочитаю эту терминологию) может отправлять новые команды через служебную шину, но это не правило, что вы должны всегда сделать это. Я реализую довольно много функций непосредственно в обработчике событий, хотя probalby будет более чистым и надежным для отправки новой команды. Это действительно зависит от того, что я хочу сделать.

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

Обычно команды обрабатываются независимо, и вы не можете гарантировать заказ (если они не обрабатываются синхронно), поэтому, возможно, вы хотите, чтобы вторая команда была выдана в результате обработки первой команды. Действительно, это может иметь место для саги.

AFAIK Вы говорите только о том, чтобы делать что-то синхронно, поэтому ваш подход работает в этом случае, но он, вероятно, не масштабируется. Перемещение на обработку async нарушит этот поток выполнения. Однако ваше приложение может быть в порядке с ним, а не каждый должен быть твиттером.

Архитектура, управляемая сообщениями, не так проста, и в некоторых случаях (например, вы хотите получить немедленный ответ от бэкэнд) это довольно сложно реализовать, по крайней мере, более сложно, чем при использовании стандартного подхода. Поэтому, возможно, для тех конкретных случаев вы можете сделать это «старым» способом.

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

+0

Спасибо за повтор! Масштабируемость является одной из самых важных в моем проекте (я хочу иметь возможность горизонтального масштабирования моего приложения), поэтому мне определенно нужно обрабатывать команду асинхронно. Я хочу использовать async и ждать от C# для этого. – mrrobot

-2

Не знаете, зачем вам нужны команды для обновления информации о стене пользователя. Почему вы решили не использовать View Model Updater для этой задачи.

Отправка электронной почты может считаться Командой, но ее также можно легко рассматривать как просто еще одно обновление модели модели.

Не ясно, что цель SendNewTripPlatformNotification, поэтому я не могу давать какие-либо предложения там ...

Часть этого также может быть кандидатом на Saga. Во-вторых, я пропущу свой домен на диаграмме, что должно отвечать за публикацию каких-либо событий или вы считаете CommandHandler доменом?