You are on page 1of 36

Part 1: Design

About This Tutorial


This tutorial demonstrates using the Edument CQRS Starter Kit in order to
build up domain logic complete with tests. We'll also see how read models can
be built, and finally how to use the domain logic and read models from a small
ASP.NET MVC application.
The tutorial will work up towards the Cafe Sample Application that is included
with the kit. Therefore, you may like to have it open to refer to as you work
through the tutorial.

The Domain
For this tutorial, we'll work in the cafe domain. Our focus will be on the
concept of a tab, which tracks the visit of an individual or group to the cafe.
When people arrive to the cafe and take a table, a tab is opened. They may
then order drinks and food. Drinks are served immediately by the table staff,
however food must be cooked by a chef. Once the chef has prepared the
food, it can then be served.
During their time at the restaurant, visitors may order extra food or drinks. If
they realize they ordered the wrong thing, they may amend the order - but not
after the food and drink has been served to and accepted by them.
Finally, the visitors close the tab by paying what is owed, possibly with a tip
for the serving staff. Upon closing a tab, it must be paid for in full. A tab with
unserved items cannot be closed unless the items are either marked as
served or cancelled first.

Events
In the scenario described above, various verbs were picked out. When
working in a database centric way, it is common to listen carefully for nouns,
mapping them to tables and relating them. Designing in terms of commands
and events puts the focus on verbs. This is good, since things that make a
domain interesting tend to be tied up in the verbs rather than the nouns. Every
business has a customer (hopefully!) - it's what they do for them that matters.
Looking through the scenario, focusing on the language we find within it, we
look for things that happen that lead to some kind of new informationin the
domain. We map these happenings to a set of events. Since events are about
things that have taken place, they are named in the past tense.

Here are a set of events we may come up with from the cafe tab scenario.

TabOpened
DrinksOrdered
FoodOrdered
DrinksCancelled
FoodCancelled
DrinksServed
FoodPrepared
FoodServed
TabClosed
Note that the events are very domain-focused. The difference between
ordering drinks and ordering food matters, so we capture these into different
events.

Commands
Commands are things that indicate requests to our domain. While an event
states that something certainly happened, a command may
beaccepted or rejected. An accepted command leads to zero or more events
being emitted to incorporate new facts into the system. A rejected command
leads to some kind of exception.
Commands are also identified by looking for verbs. However, they are focused
around what the user considers as an operation. For example, while it is
important that food and drink are handled differently in the domain, wait staff
will most certainly not want to enter drinks into the system and order them,
then separately enter food into the system, with no way to get an overview of
the order being placed! It's likely that each person at a table will specify their
food and drink together, and somebody will probably change their mind after
learning what their friend orders. Therefore, there will be a single command for
placing an order.
Here are the initial set of commands we arrive at for this domain:

OpenTab
PlaceOrder
AmendOrder
MarkDrinksServed
MarkFoodPrepared
MarkFoodServed
CloseTab
Notice how the names include a verb in the imperative mood.

Exceptions
An important part of the modeling process is thinking about the things that can
cause a command to be refused. The Edument CQRS Starter Kit is decidedly
opinionated here: we are expected to model these "sad paths" into exception
types, just as commands and events are expressed as DTOs. Furthermore,
these exception types may carry details of why the request was not
acceptable. This is because the domain logic should tell the frontend what
was wrong, rather than leaving it to ask by trying to inspect some state - or
worse, leave the user to guess.
Looking to the scenario, we can identify three notable exceptions we need in
our model:

CannotCancelServedItem
TabHasUnservedItems
MustPayEnough
The names here try to explain why the command failed.

Aggregates
Of course, man does not live by verbs alone. At some point, there has to be
nouns. More concretely, there has to be a way to talk about current state in
order to decide if a command should be accepted. For example, to refuse to
cancel a served item, we have to know that it was served.
All of the things we need are captured in the stream of past events, since they
capture all facts introduced into the system. However, somehow we need a
way to pick out the orders and servings that relate to a particular tab. More
generally, all events should be tied to some kind of entity that they together
describe the evolution and current state of.
The missing piece here is known as an aggregate. Each aggregate has its
own stream of events. Taken together, they can be used to compute its current
state. Aggregates are completely isolated from each other. Decisions about
whether to accept a command are made solely on the basis of the command
itself and the information contained in the aggregate's past events.
Concretely, an aggregate is an object. It may have internal structure (that is, it
may be built up out of many other objects), but it does not reach out to objects
outside of itself. This is demanding from a design perspective, as it forces us
to identify and segregate business concepts.
Our current example has been carefully selected to have just one aggregate
type - namely, a tab. However, in most systems you will have more work to do

in order to identify aggregates. The authors of this tutorial have found that
starting from the events and commands, then trying to group them based on
invariants (business rules you need to uphold), is a good strategy.

Moving forwards
We're now ready to start writing test cases and build up our domain logic. As
we do so, we should be ready to revisit aspects of our design, and we'll also
need to flesh out the details of what our commands and events contain.

Part 2: Domain Logic


Our First Command and Event
All scenarios start with the opening of a tab, so we'll start there. First, we
define the TabOpened event. It has a unique ID for the tab being opened, the
table number the visitors are located at, and the waiter(ess) who is serving the
table.
public class TabOpened
{
public Guid Id;
public int TableNumber;
public string Waiter;
}

None of the infrastructure in the starter kit requires events to inherit from a
particular base class. The only requirement comes from its various event store
bindings, which require a field Id of type Guid.
The command looks very similar, in this particular case:
public class OpenTab
{
public Guid Id;
public int TableNumber;
public string Waiter;
}

Once again, there is not inheritance requirement. In fact, there is no need for
a Guid Id field here either; it's just a convention.
On conventions, you may wonder whether we should suffix our command and
event type names with Command and Event. The answer is that no, it just creates
noise. It turns out that humans are really rather good at knowing if a verb is an
imperative ("Cook me a spicy burrito!") or in the past tense ("I cooked you a
spicy burrito, but then my chihuahua ate it").

Building Our First Test

Before we can write tests, we need to declare two more classes: one for our
command handler, and another for our tab aggregate.
public class TabCommandHandlers
{
}
public class TabAggregate : Aggregate
{
}

The only requirement here is that TabAggregate inherit from Aggregate.


The Aggregate base class holds the aggregate's ID and a little infrastructure
related to event application.
At this point we're ready to stub in a test class and write an initial test.
[TestFixture]
public class TabTests : BDDTest<TabCommandHandlers, TabAggregate>
{
private Guid testId;
private int testTable;
private string testWaiter;
[SetUp]
public void Setup()
{
testId = Guid.NewGuid();
testTable = 42;
testWaiter = "Derek";
}
[Test]
public void CanOpenANewTab()
{
Test(
Given(),
When(new OpenTab
{
Id = testId,
TableNumber = testTable,
Waiter = testWaiter
}),
Then(new TabOpened
{
Id = testId,
TableNumber = testTable,
Waiter = testWaiter
}));
}
}

The test says that given we have no event history for the
tab, when an OpenTab command is issued, then we expect a TabOpened event to
be produced.

By now, our solution structure looks something like this.

From Fail to Pass


We can already run our first test. And, predictably, it fails.

Happily, however, the error it fails with gives us a big hint what to do next:
CafeTests.TabTests.CanOpenANewTab: Command handler
TabCommandHandlers does not yet handle command OpenTab
Adding a command handler involves implementing the
generic IHandleCommand interface. It should be parameterized with both the
command to handle and the type of the aggregate. Note that after typing the
implementation, Ctrl + . can be used to create the stub Handle method, ready
to fill out.
public class TabCommandHandlers :
IHandleCommand<OpenTab, TabAggregate>
{
public IEnumerable Handle(Func<Guid, TabAggregate> al, OpenTab c)
{
yield return new TabOpened
{
Id = c.Id,
TableNumber = c.TableNumber,
Waiter = c.Waiter
};
}
}

The implementation of the command handler for OpenTab is straightforward; it


simply produces a TabOpened event. Note that it uses yield to make it easy for a
command handler to produce zero or many events as well as just one, like in
this case. And with this, the test passes.

Taking Orders
Next, we'll look at the process of taking orders. First up, we'll define
the DrinksOrdered and FoodOrdered events.
public class OrderedItem
{
public int MenuNumber;
public string Description;
public bool IsDrink;
public decimal Price;
}
public class DrinksOrdered
{
public Guid Id;
public List<OrderedItem> Items;
}
public class FoodOrdered
{
public Guid Id;
public List<OrderedItem> Items;
}

They share the OrderedItem class. While it is important that events remain
independent of each other, re-use of this kind is not problematic.
The command is unsurprising:
public class PlaceOrder
{

public Guid Id;


public List<OrderedItem> Items;
}

Now for the test. The tab should be opened before placing an order. At this
point, we realize that we didn't identify that failure mode earlier. That's fine; the
process of writing tests often brings about such clarifications. So we add an
exception type:
public class TabNotOpen : Exception
{
}

You can create a file per exception type, but it can be much less clutter to
create an Exceptions.cs and put all of the exceptions for an aggregate into it.
Next, we write a test:
[Test]
public void CanNotOrderWithUnopenedTab()
{
Test(
Given(),
When(new PlaceOrder
{
Id = testId,
Items = new List<OrderedItem> { testDrink1 }
}),
ThenFailWith<TabNotOpen>());
}

The failure mode of the test:


CafeTests.TabTests.CanNotOrderWithUnopenedTab: Command handler
TabCommandHandlers does not yet handle command PlaceOrder
Guides us to add a command handler, which for now can always throw, since
this is the minimum needed to pass the test.
public IEnumerable Handle(Func<Guid, TabAggregate> al, PlaceOrder c)
{
throw new TabNotOpen();
}

With that detail taken care of, now it's time to write some more interesting
tests. We map out three cases of ordering: just drinks, just food, and a mix of
food and drink. We want to make sure that items are categorized into the
correct events, and that empty drink or food order events are not emitted.
[Test]
public void CanPlaceDrinksOrder()
{
Test(
Given(new TabOpened
{

Id = testId,
TableNumber = testTable,
Waiter = testWaiter

}),
When(new PlaceOrder
{
Id = testId,
Items = new List<OrderedItem> { testDrink1, testDrink2 }
}),
Then(new DrinksOrdered
{
Id = testId,
Items = new List<OrderedItem> { testDrink1, testDrink2 }
}));
}
[Test]
public void CanPlaceFoodOrder()
{
Test(
Given(new TabOpened
{
Id = testId,
TableNumber = testTable,
Waiter = testWaiter
}),
When(new PlaceOrder
{
Id = testId,
Items = new List<OrderedItem> { testFood1, testFood1 }
}),
Then(new FoodOrdered
{
Id = testId,
Items = new List<OrderedItem> { testFood1, testFood1 }
}));
}
[Test]
public void CanPlaceFoodAndDrinkOrder()
{
Test(
Given(new TabOpened
{
Id = testId,
TableNumber = testTable,
Waiter = testWaiter
}),
When(new PlaceOrder
{
Id = testId,
Items = new List<OrderedItem> { testFood1, testDrink2 }
}),
Then(new DrinksOrdered
{
Id = testId,
Items = new List<OrderedItem> { testDrink2 }

},
new FoodOrdered
{
Id = testId,
Items = new List<OrderedItem> { testFood1 }
}));
}

All three of our new tests fail in the same way:


CafeTests.TabTests.CanPlaceDrinksOrder: Aggregate TabAggregate does not
know how to apply event TabOpened
This is where the aggregate starts to come into play. Now that we have tests
with events in the given section, we have history. And the aggregate's role in
the system is to take the events and build up a model of the current state,
which can then be used by the command handler.
The aggregate should implement the generic IApplyEvent interface for each
event type that it wishes to apply, updating its state based on the event. In this
particular case, we don't actually care about the content of the event, just that
it has taken place.
public class TabAggregate : Aggregate,
IApplyEvent<TabOpened>
{
public bool Open { get; private set; }
public void Apply(TabOpened e)
{
Open = true;
}
}

With this in place, the tests all fail in a new way:


CafeTests.TabTests.CanPlaceDrinksOrder: Expected events, but got
exception TabNotOpen
At which point we realize - ah, of course, we made our command handler
throw that exception always. Now we can go back and fill it out properly,
making our tests pass.
public IEnumerable Handle(Func<Guid, TabAggregate> al, PlaceOrder c)
{
var tab = al(c.Id);
if (!tab.Open)
throw new TabNotOpen();
var drink = c.Items.Where(i => i.IsDrink).ToList();
if (drink.Any())
yield return new DrinksOrdered

{
};

Id = c.Id,
Items = drink

var food = c.Items.Where(i => !i.IsDrink).ToList();


if (food.Any())
yield return new FoodOrdered
{
Id = c.Id,
Items = food
};
}

This is the first time that we use the first argument to the handler, al. Short
for aggregate loader, it takes the ID of an aggregate and loads it. In the case
of a test, this means applying all of the events from the given part of the test.
In production, it would load the events from some kind of event store and
apply them.

Serving - and a Pattern of Intentful Testing


Next up, we'll consider the process of serving drinks. The event produced
is DrinksServed, while the command is MarkDrinksServed. This event reflects the
domain's view (some drinks were served, and I want to incorporate this fact
into the system) and the user's view (I just gave the customer these drinks,
and now I want to mark that part of the order as served).
Defining the event is straightforward:
public class DrinksServed
{
public Guid Id;
public List<int> MenuNumbers;
}

As is the command:
public class MarkDrinksServed
{
public Guid Id;
public List<int> MenuNumbers;
}

The testing is less obvious, however. Clearly, we can write a test like this:
[Test]
public void OrderedDrinksCanBeServed()
{
Test(
Given(new TabOpened
{
Id = testId,

TableNumber = testTable,
Waiter = testWaiter
},
new DrinksOrdered
{
Id = testId,
Items = new List<OrderedItem> { testDrink1, testDrink2 }
}),
When(new MarkDrinksServed
{
Id = testId,
MenuNumbers = new List<int>
{ testDrink1.MenuNumber, testDrink2.MenuNumber }
}),
Then(new DrinksServed
{
Id = testId,
MenuNumbers = new List<int>
{ testDrink1.MenuNumber, testDrink2.MenuNumber }
}));
}

Naively, you could say that we have now tested


the MarkDrinksServed command. However, have we really? Let's see what we
need to do to make this test pass. The first reason the test fails is because of
a missing event applier:
CafeTests.TabTests.OrderedDrinksCanBeServed: Aggregate TabAggregate
does not know how to apply event DrinksOrdered
Adding a no-op handler is enough to resolve this:
public void Apply(DrinksOrdered e)
{
}

With that out of the way, the test now fails with:
CafeTests.TabTests.OrderedDrinksCanBeServed: Command handler
TabCommandHandlers does not yet handle command MarkDrinksServed
This can be fixed with a command handler that simply issues the event.
public IEnumerable Handle(Func<Guid, TabAggregate> al, MarkDrinksServed c)
{
yield return new DrinksServed
{
Id = c.Id,
MenuNumbers = c.MenuNumbers
};
}

The test does now pass, but it's somehow unsatisfying. It's almost as if we
have cheated: we got a passing test, but we've not actually written any logic

related to tracking the ordered drinks and recording their serving. In fact, all
our test really seems to assert is that we can turn a simple command into a
simple event by copying some fields from one to the other. Wow!

So how can we write tests that check we've actually written the required
domain logic? The answer typically lies in the sad paths: the tests that result in
an exception rather than events. For example, we can write tests that ensure:

You can not mark a drink as served if it wasn't ordered in the first place
You can not mark a drink as served if you already served it
Collectively, you can't serve a drink that is not still outstanding in the order.
This leads us to a new exception type:
public class DrinksNotOutstanding : Exception
{
}

One could argue that a well-behaved UI should never let the user make this
mistake. However, our domain logic should treat the sender of commands with
a degree of distrust. Responsibility for maintaining the integrity of the domain
state lies with the command handlers, which serve as a domain gatekeeper.
Having defined our new exception, we can now write a more interesting test:
[Test]
public void CanNotServeAnUnorderedDrink()
{
Test(
Given(new TabOpened
{
Id = testId,
TableNumber = testTable,
Waiter = testWaiter
},
new DrinksOrdered

Id = testId,
Items = new List<OrderedItem> { testDrink1 }

}),
When(new MarkDrinksServed
{
Id = testId,
MenuNumbers = new List<int> { testDrink2.MenuNumber }
}),
ThenFailWith<DrinksNotOutstanding>());
}

Essentially, this means that we can not mark our second test drink as served if
the order was for our first test drink. The test fails:
CafeTests.TabTests.CanNotServeAnUnorderedDrink: Expected exception
DrinksNotOutstanding, but got event result
To fix it, we have our aggregate start tracking the drinks that are still
outstanding:
private List<int> outstandingDrinks = new List<int>();
public void Apply(DrinksOrdered e)
{
outstandingDrinks.AddRange(e.Items.Select(i => i.MenuNumber));
}

Our aggregate also needs a method to check if a given set of drinks to be


served are in the outstanding list. This can be implemented by making a copy
of the outstanding items and making sure we can remove each of the ones we
wish to serve - without, of course, mutating the real thing.
public bool AreDrinksOutstanding(List<int> menuNumbers)
{
var curOutstanding = new List<int>(outstandingDrinks);
foreach (var num in menuNumbers)
if (curOutstanding.Contains(num))
curOutstanding.Remove(num);
else
return false;
return true;
}

Finally, the command handler is updated to use this method to validate the
command:
public IEnumerable Handle(Func<Guid, TabAggregate> al, MarkDrinksServed c)
{
var tab = al(c.Id);
if (!tab.AreDrinksOutstanding(c.MenuNumbers))
throw new DrinksNotOutstanding();

yield return new DrinksServed


{
Id = c.Id,
MenuNumbers = c.MenuNumbers
};
}

So, now we've tested that ordering drinks actually means something. But what
about the serving? By now, you may have started to notice a pattern: we don't
really have good test coverage until every event in our system appears in
the given clause of a sad path test. Therefore, we need to add a sad path
test involving serving of drinks. How can we do this? The easiest way is to
ensure that trying to serve an ordered drink two times fails:
[Test]
public void CanNotServeAnOrderedDrinkTwice()
{
Test(
Given(new TabOpened
{
Id = testId,
TableNumber = testTable,
Waiter = testWaiter
},
new DrinksOrdered
{
Id = testId,
Items = new List<OrderedItem> { testDrink1 }
},
new DrinksServed
{
Id = testId,
MenuNumbers = new List<int> { testDrink1.MenuNumber }
}),
When(new MarkDrinksServed
{
Id = testId,
MenuNumbers = new List<int> { testDrink1.MenuNumber }
}),
ThenFailWith<DrinksNotOutstanding>());
}

Making it pass just requires writing an Apply method for the DrinksServed event:
public void Apply(DrinksServed e)
{
foreach (var num in e.MenuNumbers)
outstandingDrinks.Remove(num);
}

We'll pass over the food workflow in the tutorial; there's no new concepts
involved with implementing it.

Closing the Tab

In some cases, commands and events end up looking the same. However,
they do not need to. It's fine for extra information to be incorporated into the
event, based on the model of history built up in the aggregate. It's also
reasonable for extra events to be emitted if a command triggers something
significant in the domain. For example, if we incorporated the notion of time to
serve food into our domain, we may wish to give a discount if some deadline
is not met. This would happen by virtue of the domain noticing the deadline
was broken and issuing an extra event granting the compensation along with
the food served event.
For closing the tab, the TabClosed event will look like this:
public class TabClosed
{
public Guid Id;
public decimal AmountPaid;
public decimal OrderValue;
public decimal TipValue;
}

This not only includes the total amount paid, but also incorporates the value of
the ordered food/drink and the amount left over, presumably given as a tip to
the waitstaff. The command, however, just includes the amount paid:
public class CloseTab
{
public Guid Id;
public decimal AmountPaid;
}

The key thing to remember is that events are domain-facing,


whereas commands are user-facing. The contents of events should, of
course, capture all that is to be persisted for the future. But it is allowable to
include extra information, to save code outside of the domain having to do
recalculations and thus avoiding logic leaks. Sometimes, implementing event
consumers (such as read sides) will provide feedback that will influence the
contents of events.
Here is a test case for closing a tab and paying a tip (there is also a test for
paying the exact amount in the sample app):
[Test]
public void CanCloseTabWithTip()
{
Test(
Given(new TabOpened
{
Id = testId,
TableNumber = testTable,
Waiter = testWaiter
},

new DrinksOrdered
{
Id = testId,
Items = new List<OrderedItem> { testDrink2 }
},
new DrinksServed
{
Id = testId,
MenuNumbers = new List<int> { testDrink2.MenuNumber }
}),
When(new CloseTab
{
Id = testId,
AmountPaid = testDrink2.Price + 0.50M
}),
Then(new TabClosed
{
Id = testId,
AmountPaid = testDrink2.Price + 0.50M,
OrderValue = testDrink2.Price,
TipValue = 0.50M
}));
}

As we try to make this pass, we realize that our aggregate hasn't been
keeping track of the prices of the items served. The prices arrive in
thePlaceOrder command, but should not contribute to the bill until the items
have been served.
One of the advantages of working in terms of events, and only building up the
aggregate when we need it, is that we have the freedom to change the
models in our aggregates as our domain understanding grows. Naturally, this
applies during the initial development. But even after a system enters
production, we are still able to evolve our aggregate in the face of new
requirements.
This time, the changes are relatively straightforward. Currently, we just keep
track of the menu numbers of the ordered items:
private List<int> outstandingDrinks = new List<int>();
private List<int> outstandingFood = new List<int>();
private List<int> preparedFood = new List<int>();

However, there's nothing to stop us keeping more information about the


ordered items around:
private List<OrderedItem> outstandingDrinks = new List<OrderedItem>();
private List<OrderedItem> outstandingFood = new List<OrderedItem>();
private List<OrderedItem> preparedFood = new List<OrderedItem>();

The event applier for DrinksOrdered actually gets simpler, going from:
public void Apply(DrinksOrdered e)
{
outstandingDrinks.AddRange(e.Items.Select(i => i.MenuNumber));

To just:
public void Apply(DrinksOrdered e)
{
outstandingDrinks.AddRange(e.Items);
}

It's a similar story for FoodOrdered. Next, we introduce a property that we will
use to tally the value of served food and drink:
public decimal ServedItemsValue { get; private set; }

The event handler changes from simply removing menu numbers:


public void Apply(DrinksServed e)
{
foreach (var num in e.MenuNumbers)
outstandingDrinks.Remove(num);
}

To locating the served drink by menu number, removing it from the


outstanding drinks list, and adding its price to the total:
public void Apply(DrinksServed e)
{
foreach (var num in e.MenuNumbers)
{
var item = outstandingDrinks.First(d => d.MenuNumber == num);
outstandingDrinks.Remove(item);
ServedItemsValue += item.Price;
}
}

Similar changes apply to other event appliers. Finally, we are in a position to


add another command handler:
public IEnumerable Handle(Func<Guid, TabAggregate> al, CloseTab c)
{
var tab = al(c.Id);
yield return new TabClosed
{
Id = c.Id,
AmountPaid = c.AmountPaid,
OrderValue = tab.ServedItemsValue,
TipValue = c.AmountPaid - tab.ServedItemsValue
};
}

This is, of course, not complete yet. We need tests to cover the sad paths,
including one for closing tabs. You can find these in the sample application;
there is nothing especially notable about them.

Domain First
We have been able to focus strongly on the domain and its language as we
have gone about our development. Along the way, we discovered new failure
modes and incorporated those into our model. We didn't have to be
concerned with the details of persistence, or use any mock/stub objects to
keep our business logic isolated from the environment. And the tests that we
have built are really just data, which we could easily use to produce a report
or some other document that we can discuss with a domain expert.
While focusing on the domain and domain logic is important, it's not the only
thing we must develop in order to have a complete system. In fact, at present
our system can only accept/reject commands. We have nothing that we can
query for current state. This is what we will be concerned with in the next
section.

Part 3: Read Models


Read Models are about Queries
The domain logic that we built in the previous section accepted commands
from the outside world. Sending a command is a void operation; either the
command is accepted and life goes on, or the command is rejected and an
exception is thrown. So how does the outside world ever ask questions about
current state? This is where read models come in.

A read model is a model specialized for reads, that is, queries. It takes
events produced by the domain and uses them to build and maintain a model
that is suitable for answering the client's queries. It can draw on events from
different aggregates and even different types of aggregate. What it does from
there is unimportant. It may build and maintain...
An in-memory model of the data
A relational model of the data, stored in an RDBMS
Documents, stored in a document database
A graph model of the data, stored in a graph database
A search index
An XML file, CSV file, Excel sheet, etc.
You get to choose - and furthermore, you get to make the decision per read
model (providing a concrete way to realize polyglot persistence). Moreover,
multiple read models can be built from the same event. After all, events
represent facts that have already been incorporated into the system. They are

the normalized part of our system, and read models are a point of potential
denormalization. If that makes your inner relational animal feel scared, it's
worth remembering that you probably turn normalized data into denormalized
data all the time - using the JOIN operator in SQL. We're just choosing to do
the denormalization at a different point - potentially paying for it once per
change rather than once per query.
A read model could even, instead of exposing methods to do queries, expose
push collections, using Rx to turn streams of events from the domain into
objects suited to maintaining some kind of reactive UI. Thus, this approach fits
very well with reactive programming also.
In this tutorial, we'll build in-memory read models. However, the step up to
making a persistent read model, stored in a database or file of some kind, is
small. You can use all the familiar tools you wish to do it, too; there's nothing
wrong with implementing your read model using Linq to SQL, if it is the most
expedient way and will give you the performance you desire.

What read models will we need?


To get an idea of what read models are needed, we should start by looking at
different scenarios where we need to present information to the users of the
system. Wait staff need to see:

The current list of open tabs


The current tab for a particular table, with an indication of the status of
each item
The drinks that they need to serve
Any food that is prepared and ready to be served to the table
Chefs need to see:

The current list of food that has been ordered and needs to be prepared
Cashiers need to see:

The tab for a table, and the total amount to be paid


The queries that involve tab viewing seem highly related, and can probably
just be methods returning information based on a single model. The queries
where a particular member of wait staff can see the food/drink they should
serve as soon as possible also feel related; we may even want to return the
two together. The query for showing chefs food that needs preparing feels like
a separate concern, and so we may wish to keep that distinct.

Overall, it feels like there are three read models to build:

A chef todo list read model


A wait staff todo list read model
A tab read model
We'll look in detail at building the chef todo list.

The Chef Todo List


Maintaining the todo list for chefs involves reacting to two events:

FoodOrdered,

which adds food to prepare onto the todo list


FoodPrepared, which removes prepared food from the todo list
We'll implement read models as classes, which implement
the ISubscribeTo generic interface in order to subscribe to events:
public class ChefTodoList :
ISubscribeTo<FoodOrdered>,
ISubscribeTo<FoodPrepared>
{
// ...
}

While the naive approach is just to push all items to prepare into a list,
typically food that is ordered together should be delivered together. Thus, the
grouping should be retained - while realizing that a chef may violate it in
certain circumstances. Therefore,we'll declare two DTOs to represent the todo
list entries.
public class TodoListItem
{
public int MenuNumber;
public string Description;
}
public class TodoListGroup
{
public Guid Tab;
public List<TodoListItem> Items;
}

The read model will maintain a List of TodoListGroup:

private List<TodoListGroup> todoList = new List<TodoListGroup>();

Since changes to the todo list and requests for it may arrive concurrently, we
must take care to be thread safe. Furthermore, we should never leak the
internal todo list. In fact, we must not leak the internal list of items per group
either, since those can also change over time. Thus, we should write
theGetTodoList method something like this:
public List<TodoListGroup> GetTodoList()

lock (todoList)
return (from grp in todoList
select new TodoListGroup
{
Tab = grp.Tab,
Items = new List<TodoListItem>(grp.Items)
}).ToList();

Note that we need to take care of the locking here as we're keeping a mutable
model around in memory. If your builders always wrote into a database and
your query methods already read from one, then you are most likely free of
these issues (because you've left them for the database to deal with).
What about the methods that will build the todo list? New orders are a fairly
simple bit of mapping:
public void Handle(FoodOrdered e)
{
var group = new TodoListGroup
{
Tab = e.Id,
Items = new List<TodoListItem>(
e.Items.Select(i => new TodoListItem
{
MenuNumber = i.MenuNumber,
Description = i.Description
}))
};
lock (todoList)
todoList.Add(group);
}

The FoodPrepared handler has a little more to think about. First, it should
remove all of the prepared items from the group. Then, if nothing remains in
the group, the group itself should also be removed.
public void Handle(FoodPrepared e)
{
lock (todoList)
{
var group = todoList.First(g => g.Tab == e.Id);
foreach (var num in e.MenuNumbers)
group.Items.Remove(
group.Items.First(i => i.MenuNumber == num));

}
}

if (group.Items.Count == 0)
todoList.Remove(group);

Two Become One


The next read model to implement is the wait staff todo list. There's nothing
particularly new from an implementation perspective. It subscribes to all of the
events, since the whole lifecycle matters for maintaining the todo list for wait
staff. Of note, the descriptions are included in the event issued at the point of
ordering, so even though we don't need to present food items in the list at that
point, we still want to record the information associated with them, adding
them to the list of things to serve at the point the FoodPrepared event arrives.
After implementing this read model, the key data structure looked something
like this:
public class ItemTodo
{
public int MenuNumber;
public string Description;
}
public class TableTodo
{
public int TableNumber;
public string Waiter;
public List<ItemTodo> ToServe;
public List<ItemTodo> InPreparation;
}
private Dictionary<Guid, TableTodo> todoByTab =
new Dictionary<Guid,TableTodo>();

With the to-serve list per query looking as follows:


public Dictionary<int, List<ItemTodo>> TodoListForWaiter(string waiter)
{
lock (todoByTab)
return (from tab in todoByTab
where tab.Value.Waiter == waiter
select new
{
TableNumber = tab.Value.TableNumber,
ToServe = CopyItems(tab.Value)
})
.Where(t => t.ToServe.Count > 0)
.ToDictionary(k => k.TableNumber, v => v.ToServe);
}

What's striking is that we essentially end up storing information about the tab
overall. With a few extensions, this read model would also be able to answer
queries related to tabs. Therefore, we can simplify our original plan, having
just two read models. The resulting new read model is calledOpenTabs, because
its focus is on queries related to tabs that are currently open. See the sample
application for the full details.

It's important to remain open to course corrections such as this during the
development process. Things that a developer can see as they build a system
differ from those a domain expert can see, which can lead to simplifications
and new opportunities.

Safety Through Interfaces


As handling of events is done through interface implementation,
the Handle methods are public. However, we really don't want those writing
query code to call them. Also, coupling directly to classes is bad object
oriented design. Therefore, we'll extract a couple of interfaces from our read
models:
public interface IChefTodoListQueries
{
List<ChefTodoList.TodoListGroup> GetTodoList();
}
public interface IOpenTabQueries
{
List<int> ActiveTableNumbers();
OpenTabs.TabInvoice InvoiceForTable(int table);
OpenTabs.TabStatus TabForTable(int table);
Dictionary<int, List<OpenTabs.TabItem>> TodoListForWaiter(string waiter);
}

These will be used by the web frontend, which we will look at next.

Part 4: Web Application Integration


Planning
We'll build our front end application using ASP.NET MVC. The overall idea is
to use queries to obtain data and send commands in order to effect changes
in the system. Since the commands and queries were designed with user
tasks in mind, the mapping should be easy or non-existent (that is, we use the
query DTOs or command objects directly as the view model).
The web application needs to provide:

Creation of new tabs when visitors arrive and take a table


Adding of food and drink orders to a tab
Viewing of a tab's current status: what is to serve, in preparation and
already served
A list of outstanding items to serve per member of wait staff
A list of food to prepare, for chefs

A way for a cashier to obtain an invoice and, upon payment, close the

tab

Menus and Wait Staff


Having seen how nicely we implemented tabs, using events and writing
intentful tests, it may seem tempting to go ahead and create aggregates for
the menu and the wait staff list. But wait...what will we gain from this? Tabs
are at the heart of the cafe's operations. They follow an interesting workflow,
which happens many times a day and needs to be got right. By contrast, there
is very little to validate, and nearly no invariants to enforce, when it comes to a
menu and a list of wait staff. It's just...data. And what do we do with it? CRUD.
For the sake of this example, we won't even build tools for manipulating it.
Instead, we'll just have a file of static data:
public class MenuItem
{
public int MenuNumber;
public string Description;
public decimal Price;
public bool IsDrink;
}
public static List<MenuItem> Menu = new List<MenuItem>
{
new MenuItem
{
MenuNumber = 1, Description = "Coke", Price = 1.50M, IsDrink = true
},
/...
new MenuItem
{
MenuNumber = 10, Description = "Mushroom & Bacon Pasta", Price = 6.00M
},
// ...
};
public static List<string> WaitStaff = new List<string>
{
"Jack", "Lena", "Pedro", "Anastasia"
};

The takeaway message here is that not everything in your system will benefit
from intentful testing, event sourcing, DDD and so forth. Apply it in the core
domain. For the stuff that needs to be there but isn't the core driver of
business value, do the cheapest thing - but couple to it loosely.

Setup

We need instances of the message dispatcher to send commands. We also


need instances of the read models, and need the message dispatcher to send
events to them. We may wish to dependency inject all of these things into our
controllers - but to keep this example simple, we'll just have a static class with
a setup method called from our Global.asax.cs.
public static class Domain
{
public static MessageDispatcher Dispatcher;
public static IOpenTabQueries OpenTabQueries;
public static IChefTodoListQueries ChefTodoListQueries;
public static void Setup()
{
Dispatcher = new MessageDispatcher(new InMemoryEventStore());
Dispatcher.ScanInstance(new TabCommandHandlers());
OpenTabQueries = new OpenTabs();
Dispatcher.ScanInstance(OpenTabQueries);
ChefTodoListQueries = new ChefTodoList();
Dispatcher.ScanInstance(ChefTodoListQueries);
}

Common Links
To make for easy navigation, we want all pages to display a set of links for
each member of wait staff's todo lists, and another set linking to the status
page for each open tab. We'll use ASP.NET MVC's ViewBag to store this data,
accessing it from the page layout. Since we will want this for almost all of the
pages, we'll factor out the logic to add it to an action filter.
public class IncludeLayoutDataAttribute : ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext
filterContext)
{
if (filterContext.Result is ViewResult)
{
var bag = (filterContext.Result as ViewResult).ViewBag;
bag.WaitStaff = StaticData.WaitStaff;
bag.ActiveTables = Domain.OpenTabQueries.ActiveTableNumbers();
}
}
}

Notice how this makes a call to a read model. The layout can then incorporate
this information into the navigation.
<li class="nav-header">Wait Staff Todo Lists</li>
@foreach (var w in ViewBag.WaitStaff as List<string>)

{
<li>@Html.ActionLink(w, "Todo", "WaitStaff", new { id = w }, null)</li>
}
<li class="nav-header">Open Tabs</li>
@foreach (var t in ViewBag.ActiveTables as List<int>)
{
<li>@Html.ActionLink(t.ToString(), "Status", "Tab", new { id = t }, null)</li>
}

Opening A Tab
Opening a tab is done by sending an OpenTab command. The job of the web
application is to collect information to populate that command. One obvious
thing we could do is use the command as the model for the page - and in fact,
that will work out very nicely here. Thus, here is the Razor view:
@model Cafe.Tab.OpenTab
<h2>Open Tab</h2>
@using (Html.BeginForm())
{
<fieldset>
<label>Table Number</label>
@Html.TextBoxFor(m => m.TableNumber)
<label>
Waiter/Waitress
</label>
@Html.DropDownListFor(m => m.Waiter, (ViewBag.WaitStaff as List<string>)
.Select(w => new SelectListItem { Text = w, Value = w }))
<br>
<button type="submit" class="btn">Submit</button>
</fieldset>
}

We can then use model binding in order to have the MVC framework
instantiate and populate the command object for us, leaving us to fill in a Guid
for the tab we wish to open (a fresh Guid because this command should
happen on a new aggregate) and send the command using the dispatcher.
public ActionResult Open()
{
return View();
}
[HttpPost]
public ActionResult Open(OpenTab cmd)
{
cmd.Id = Guid.NewGuid();
Domain.Dispatcher.SendCommand(cmd);
return RedirectToAction("Order", new { id = cmd.TableNumber });
}

This almost works - but not quite! It turns out that MVC model binding will not
work with fields, only with properties. This is not a big problem; we just tweak
our command a little:
public class OpenTab
{
public Guid Id;
public int TableNumber { get; set; }
public string Waiter { get; set; }
}

Note this makes explicit what fields we welcome model binding of and which
should not be controllable from the web.

Ordering
Placing an order also involves issuing a command. This time, it's not quite so
easy to have the command as the model, but we can define a model that will
be easy to map to the command.
public class OrderModel
{
public class OrderItem
{
public int MenuNumber { get; set; }
public string Description { get; set; }
public int NumberToOrder { get; set; }
}
public List<OrderItem> Items { get; set; }
}

This can be built up from the static menu data:


public ActionResult Order(int id)
{
return View(new OrderModel
{
Items = (from item in StaticData.Menu
select new OrderModel.OrderItem
{
MenuNumber = item.MenuNumber,
Description = item.Description,
NumberToOrder = 0
}).ToList(),
});
}

And rendered using a relatively straightforward view:


@model WebFrontend.Models.OrderModel

<h2>Place Order</h2>
@using (Html.BeginForm())
{
<fieldset>
<table class="table">
<thead>
<tr>
<td>Menu #</td>
<td>Description</td>
<td>Number To Order</td>
</tr>
</thead>
<tbody>
@for (int i = 0; i < Model.Items.Count; i++)
{
<tr>
<td>
@Model.Items[i].MenuNumber
@Html.HiddenFor(m => m.Items[i].MenuNumber)
</td>
<td>@Model.Items[i].Description</td>
<td>@Html.TextBoxFor(m => m.Items[i].NumberToOrder)</td>
</tr>
}
</tbody>
</table>
<button type="submit" class="btn">Place Order</button>
</fieldset>
}

We can again use model binding to have the form data mapped
into OrderModel. Then, we do a little bit of mapping to turn it into
the PlaceOrdercommand and send it using the dispatcher. We also need to
resolve the table number to its tab's ID.
[HttpPost]
public ActionResult Order(int id, OrderModel order)
{
var items = new List<Events.Cafe.OrderedItem>();
var menuLookup = StaticData.Menu.ToDictionary(k => k.MenuNumber, v => v);
foreach (var item in order.Items)
for (int i = 0; i < item.NumberToOrder; i++)
items.Add(new Events.Cafe.OrderedItem
{
MenuNumber = item.MenuNumber,
Description = menuLookup[item.MenuNumber].Description,
Price = menuLookup[item.MenuNumber].Price,
IsDrink = menuLookup[item.MenuNumber].IsDrink
});
Domain.Dispatcher.SendCommand(new PlaceOrder
{
Id = Domain.OpenTabQueries.TabIdForTable(id),
Items = items
});

return RedirectToAction("Status", new { id = id });


}

Note that TabIdForTable is a method added to the read model, having realized
while building the web application that it would be useful. This is a normal
thing to do; after all, the queries are there to serve the needs of clients.

The Wait Staff Todo List


Queries are meant to be close to what we expect to present to the user. As a
result, the DTO returned by a query will often be suitable as a model for the
view. In that case, we can do something as simple as:
[IncludeLayoutData]
public class WaitStaffController : Controller
{
public ActionResult Todo(string id)
{
ViewBag.Waiter = id;
return View(Domain.OpenTabQueries.TodoListForWaiter(id));
}
}

The view simply takes the model and renders it out as HTML. Note that we
take care to include a helpful link to the tab status page for each table we
should serve to.
@model Dictionary<int, List<CafeReadModels.OpenTabs.TabItem>>
<h2>Todo List For @ViewBag.Waiter</h2>
@foreach (var table in Model)
{
<h3>Table @table.Key</h3>
<table class="table">
<thead>
<tr>
<th>Menu #</th>
<th>Description</th>
</tr>
</thead>
<tbody>
@foreach (var item in table.Value)
{
<tr>
<td>@item.MenuNumber</td>
<td>@item.Description</td>
</tr>
}
</tbody>
</table>

@Html.ActionLink("Go To Tab", "Status", "Tab",


new { id = table.Key }, null)

There's nothing particularly exciting here; we really are just taking data out of
the read model and rendering it using the view.

The Chef Todo List


The action method is no more involved:
public class ChefController : Controller
{
public ActionResult Index()
{
return View(Domain.ChefTodoListQueries.GetTodoList());
}
}

The view, however, is a bit more interesting this time. We need to offer a way
to mark items as prepared. This needs a little care, because it's possible a
chef will manage to prepare only some of the items together, so we must offer
a way to mark out those that have been prepared. We'll use check boxes, to
keep things relatively simple.
@model List<CafeReadModels.ChefTodoList.TodoListGroup>
<h2>Meals To Prepare</h2>
@foreach (var group in Model)
{
var i = 0;
using (Html.BeginForm("MarkPrepared", "Chef"))
{
@Html.Hidden("id", group.Tab)
<table class="table">
<thead>
<tr>
<th>Menu #</th>
<th>Description</th>
<th>Prepared</th>
</tr>
</thead>
<tbody>
@foreach (var item in group.Items)
{
<tr>
<td>@item.MenuNumber</td>
<td>@item.Description</td>
<td>@Html.CheckBox(string.Format("prepared_{0}_{1}",
i++, item.MenuNumber.ToString()))</td>
</tr>

}
</tbody>
</table>
<button type="submit" class="btn">Mark Prepared</button>
<hr />
}

Often, views will end up playing this dual role: showing data from a read
model and also providing a way to issue some command to do the next piece
of work.

The Rest
The other operations that make up the web application are variations on the
things we've already seen in this tutorial, so we won't go over them in more
detail here. See the sample application if you're curious.

Task Based UI
Intentful testing leads us to commands that express domain-significant acts.
This in turn tends to be reflected in the UI, which is now focused on tasks
rather than editing. Since queries are developed according to the kinds of
reports that we need to present, they can also focus on what the user really
needs to see as they use the system.
This helps us to avoid the trap, common in systems that evolve from
designing a relational database, of everything really being about editing. Of
course, just creating commands isn't a magical promise of everything. If we'd
failed to focus on the language of the domain language, we may have ended
up with commands like CreateTab, UpdateTab and DeleteTab. In essence, we'd
have gone to all this effort only to recreate a CRUD system - one we could
have realized in a much more expedient manner!
All the pieces - intentful testing, a focus on the verbs, separating out the
handling of commands and queries, and task based UI - make a coherent
whole. They are best applied to the core domain, where it makes sense to
invest in building domain understanding, solid tests, and loose coupling with
the outside world.

Part 5: Other Matters


We've now built up the sample application. This final section features a few
topics that are worth considering if you plan to build a production system in
this style. The Edument CQRS starter kit really is just that: a start. It's up to
you to finish it with the things you need for a production ready system.

Two Commands, One Aggregate


What happens if two commands arrive at around the same time, and the
command handlers wish to yield events on the same aggregate? Since
aggregates are built up each time, there is no risk of the two executions
interfering. However, only one will manage to get its events stored. The
second will lose: it is not allowed to store its events because they were
produced based on an inconsistent view of history. The rule underlying this is
really simple: the number of events the aggregate had at the point you loaded
it must be the number it has at the point you try to persist the new events.
There are some interesting outcomes of this. One is that you have a global
progress bound: the only way you can fail to persist new events is because
something else was successful. However, more interesting is what you should
do if you can't apply the events.
When this happens with the starter kit as provided, it just results in an
exception being thrown. However, there is another option. You could catch
such exceptions in MessageDispatcher and try to re-run the command handler.
This means it will act on the latest events, and (provided nothing beats it
again) can get its work done. Since command handlers only look at the
aggregate and the incoming command and yield the events they wish to
apply, they are pure. This means trying again is harmless.
Of course, there's nothing to enforce such purity on you. For example, you
could potentially write a command handler that sends an email. This is a bad
idea, since a conflict may follow and the command handler may have to run
again. This could lead to a duplicate email, or worse it could lead to the
command failing due to the events that it did not see the first time, meaning
the email now tells that receiver about a reality that never came to be.

Transactionality of Event Handlers


Another concern we may have is what happens if events are persisted, but
then we fail to update the read models. In this case, it's easy to see the risk of
things getting desynchronized, which is clearly undesirable. There are a few
options.
If all of the stores involved can participate in a transaction, then you could
potentially surround the call to the command handler, applying of events and
calls to the event subscribers in a TransactionScope. This is a relatively easy
change to the MessageDispatcher, and it gives a pretty good promise of

consistency. However, it's not quite a free lunch. Here's some things you may
need to be aware of if you take this approach.
You need to be using an event storage that knows about transactions. If
you use a event store that is really a couple of SQL Server database tables,
for example, then you're covered.
You need the read models to also be persisting in a way that
participates in the transaction.
The failure of one read model cascades out to a complete failure to
apply the command. (Note that whether this is good or bad is system specific.)
Not everything can be transactional (like sending email).
There are a couple of alternatives that are worth mentioning. One is to use a
store-and-forward message queue to implement the publish/subscribe of
events. The placing of the events into the queue and the persistence of the
events to storage need to happen within a transaction. MSMQ and SQL
Server can be used this way, for example (but beware the distributed
transaction coordinator). The benefit of this is that as soon as the event is in
the subscriber's queues, you're done. Read models can individually and
transactionally receive their copy of the message. This means:

Failure of a single read model affects only that read model


There are multiple short-lived transactions rather than one big one
Read models become eventually consistent. This is a big deal and
you must plan how to deliver a good user experience in the light of it!
The message queue provides a strategy to scale out over multiple
processes, hardware, etc.
BUT, you've just started writing a distributed system!
Since using such a setup brings the system to a state of eventual consistency
anyway, it may be simpler to switch to a pull-based approach. Instead of using
a message queue, the read models simply poll for the latest events in the
store. By giving each event stored an ascending number, it is possible for read
models to know the last event they incorporated into the model and query for
any new ones. This means that the update rate is chosen by the read model,
which allows fine-grained contorl over SLA. It is also easy to scale out, as
events are easily replicated. AtomPub is one way to do this. Using the Greg
Young event store, you get an atom interface built in.

Coping with Eventual Consistency


Of the approaches above, two of them lead to eventual consistency. There is
no way to sweep that under the carpet: it will have consequences for the way
you build the rest of the system. However, to repeat the advice already given

many times in this tutorial, the approach suggested here is aimed at your
core domain.
The typical CRUD system, with a grid of things to edit, has potential to be a
nightmare if you have eventual consistency. Why? Because when the user
adds or edits items, they expect to return to the grid and see it updated with
what they just did. If the grid is being updated by doing a query each time,
then there's no promise the update will have already taken place in the
appropriate read model.
Task based UIs, because they're about taking the user through a workflow,
tend to be less problematic in this regard, however. And doing task based UIs
for the core domain is often a worthwhile investment.

You might also like