views:

116

answers:

1

Reading up on CQRS there is a lot of talk of email notification - i'm wondering where to get the data from. Imagine a senario where one user invites other users to an event. To inform a user that he has been invitet to an event, he is send an email.

The concrete mecanics might go like this:

  1. A "CreateEvent" command with an associated collection of user to invite, is received by the server.
  2. A new meeting aggregate is created and a method "InviteUser" is called for each user that is to be invited.
  3. Each time a user is invited to an event, a domain event "UserWasInvitedToEvent" is raised.
  4. An email notification sender picks up the domain event and sends out the notification email.

Now my question is this: Where do i go for information to include in the email?

Say i want to include a description of the event as well as the users name. Since this is CQRS i can't get it thru my domain model; All the properties of the domain objects are private! Should i then query the read side? Or maybe move email notification to a different service entirely?

Any thoughts will be much appriciated!

+1  A: 

In CQRS, you're separating the command from the query side. You will always want to go to the query side in order to get data for a given event handler. The write database is going to be a separate database that contains the data necessary for building up your domain objects and will not be optimized for reads, but for writes.

  1. The domain should register and send an EventCreated event to the event handlers / processors. This could be raised from the constructor of the Meeting aggregate.
  2. The event processing component would pick up the EventCreated event, and update the query database with the data contained in the event (ie, the Id of the event and its name).
  3. The domain could register and send a UserWasInvitedToEvent event to the event processors.
  4. The event processors would pick up the UserWasInvitedToEvent and update the query store with any reporting data necessary.
  5. Another event processing component would also pick up the UserWasInvitedToEvent event. This process could have access to the query database and pull back all of the data necessary for sending the email.

The query database is nothing more than a reporting database, so you could even have a specific table that stores all of the data required for the email in one place.

In order to orchestrate several different events into a single handler (assuming the events might be processed in a different order at different times), you could utilize the concept of a Saga in your messaging bus. NServiceBus is an example of a messaging bus that supports Saga's. See this StackOverflow question as well: NServiceBus Delayed Message Processing.

JD Courtoy
It's incredible how much difference a single word can make. I meant to say query the READ side ofcours! I am aware of the basics of CQRS :) Anyways, what you are saying is you would go to the query store for the data to include in the email?I can see how this could pose a problem, as the query store might not nessesery be up to date, when the UserWasInvitedToEvent event arrives.One possible solution could be a component / service that would listen for new meetings, user and invitations and store that data, so it could send out invitations?
t0PPy
Yes, that is what I was getting at. There are such things as Saga's in certain messaging frameworks such as NServiceBus that allow you to orchestrate several event handlers that do not necessarily arrive in the same order each time. You may want to look into that as well. These act as a workflow of sorts that would allow you to wait on all pertinent information before performing some action.
JD Courtoy