diyes: laying the foundation

For the more lazy ones that decided to skip the event sourcing literature that I suggested in my first post, I will try to explain a bit of how it works. Bear in mind, I am myself try to get to understand better how  Event Sourcing (ES) and CQRS so my explanations might not be the best.

So basically, instead of having objects containing a state to represent our business objects, with event sourcing we have a sequence of events that describe what happened to our aggregates (in ES these business objects are called aggregates).

I will try to show an example of how to do the same thing in  both non-ES and ES way. Imagine we are trying to model a shopping cart system for our application.

  • Non-ES way: when an user of our system adds an item A to the cart we create an empty ShoppingCart object, and  we will probably call a method called AddItem which adds the item A to the cart. The object will then be saved in our relational or maybe even NoSql database. When the user adds an item B his cart, we will load his shopping cart from our db and then proceed to call the AddItem again.
  • ES way: when an user of our system adds an item A to the cart instead of creating an object we will instead emit an event that represents that the shopping cart was created, and then another event which represents that the item A was added to the shopping card. The events are then saved in our event store. When the user adds the item B to the cart, we retrieve the events related with the card, we can see that it was created, it had item A added to it, and then proceed to emit an event that represents the item B being added to the cart.

Both approaches don’t seem much different right? But imagine now the user decided to remove item A from the shopping cart. In the non-ES way, if we look at the database we only can see a cart with the item B. If we looked at the ES way we would have an extra event saying the item A had been removed from the cart. Using event sourcing is like having an inbuilt audit-engine for your whole application.

So from our little story before we saw that at the foundation of an event sourcing library there must be a place where you can save and load events, the event store.

Our event store will have a simple interface which allows the realization of these two simple operations load and save.

public interface IEventStore
  EventStream LoadEventStream(IIdentity id);
  void AppendToStream(IIdentity id, int originalVersion, IEnumerable<IEvent> events);

This is basically all we need. The LoadEventStream method has as parameter the identity of the aggregate which we want to load events for and returns an EventStream (all the events for that aggregate). The AppendToStream method receives the identity of the aggregate we want to store the events for, the original version of the stream (I will explain this a bit below) and the series of events we want to save.

An EventStream is basically a list of events and an number indicating the version of the aggregate. The version is needed so we can prevent concurrent writes to the event store from corrupting our data.

public class EventStream
  public int Version;
  public List<IEvent> Events = new List<IEvent>();

If you are interested in checking out how I implemented the event store interface check out my code from Github.

The code is more or less simple and there isn’t many classes to investigate yet, the unit tests show how the event store can be used. The current implementation of the event store works only in-memory, but I hope in the future to implement a persistent event store using some db (probably MsSQL or Ravendb).

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s