Adding a persistent event store

Right now, the Simple.CQRS application use an in-memory event store, which means all events are lost when the MVC application unloads. The read model is also only kept in memory.

Instead of building my own even store, I choose to use Jonathan Oliver’s [1] event store [2], which supports a wide variety of persistence engines. I picked MongoDB [3], basically just because I never had used MongoDB before.


Installing MongoDB [4] was a breeze and I had it up-and running in no time. I found the post Getting started with MongoDB on .net [5] a good starting point. For exploring databases (and for viewing diffs), I prefer using a GUI over the command line, so I installed MongoVue [9]. I had some issues with serialization, which were solved by registering my event types with MongoDB [7] [8].

Finding the seams …

Simple.CQRS defines a SimpleCQRS.IEventStore interface:

public interface IEventStore
    void SaveEvents(Guid aggregateId, IEnumerable<Event> events, int expectedVersion);
    List<Event> GetEventsForAggregate(Guid aggregateId);

Simple enough; I figured I’d just implement that interface using Oliver’s event store.

I choose not to persist the read model, but instead replay all events on application startup, which rebuilds the in-memory read model. Only thing we have to do, is provide a way to get all events from the event store, so I introduced:

internal interface IGetAllEvents
    Event[] GetAll();

Hook into the seams

Well, just implement the above interfaces, full code on Github

public class EventStore : SimpleCQRS.IEventStore, IGetAllEvents
    private IStoreEvents _store;

    public EventStore(EventStore.IStoreEvents store)
        _store = store;

    public void SaveEvents(Guid aggregateId, IEnumerable<Event> events, int expectedVersion)
        // snip ... see github

    public List<Event> GetEventsForAggregate(Guid aggregateId)
        // snip ... see github

    public Event[] GetAll()
        return _store.Advanced.GetFrom(DateTime.MinValue)
            .SelectMany(c => c.Events)

This event store is initialized in global.asax

private static CQRSGui.Infra.EventStore GetWiredEventStoreWrapper()
    var types = Assembly.GetAssembly(typeof(SimpleCQRS.Event))
                                .Where(type => type.IsSubclassOf(typeof(SimpleCQRS.Event)));
    foreach (var t in types)

    var store = Wireup.Init()
        .UsingMongoPersistence("mongo", new DocumentObjectSerializer())
        .DispatchTo(new DelegateMessageDispatcher(DispatchCommit))

    return new CQRSGui.Infra.EventStore(store);

And then passed to the SimpleCQRS repository as a SimpleCQRS.IEventStore.

Rebuilding the read model

After wiring up the event store, we have to replay all events to rebuild the in-memory read model:

private void RebuildReadModel(IGetAllEvents store, FakeBus bus)
    foreach (var e in store.GetAll())

This is a hack; imagine we had hooked up an email event handler that mailed our boss when an inventory item was deactivated: the mail would be resend every time the app started.

But for now it works.


[1]You might remember him from People in CQRS
[2] and
[5]Getting started with MongoDB on .net
[6]Serialization using the MongoDB c# driver <>