Event Sourcing example with EventStore and .NET

Hi,

First of all sorry if this isn’t the place for a post like this. I’m new here.

Just completed an project demonstrating the Event Sourcing pattern using C# and EventStore complete with AggregateRoot.

https://github.com/dasiths/EventSourcingDemo

Thought I’d ask you guys for some feedback regarding the use of EventStore and if there are areas to improve on.

Thanks again.

Regards,

Dasith

The project has been moved to: https://github.com/dasiths/NEventLite

NEventLite - Light weight .NET framework for Event Sourcing with support for custom Event and Snapshot Stores (EventSore, Redis, SQL Server or Custom) written in C#.

Not bad. I’ve seen a lot of these ES domain implementations lately.

If you want to stick strictly to the design patterns, I’d probably take Save() off the repository and move it to a new class of type EventStoreUnitOfWork that implements a simple IUniwOfWork.Commit() method instead.

The unit of work can then coordinate access to the repository, track changes to the aggregate and be responsible for writing changes (events) back to ES.

Aggregate changes can be tracked using event handlers or just passing an Action to an aggregate during construction.

The unit of work can resolve any concurrency issues itself or it can delegate back to the aggregate if needed. The original command could even provide some hint how to resolve a concurrency issues (ignore, retry, etc)

Commit can flush a collection of raised events back to ES, or Rollback (basically do nothing).

That keeps the aggregate nice and clean and your command handlers end up being, at most, 3 lines of code.

Thanks Andrew. We think alike. I want to implement Unit Of Work too. I have to implement a way to track Aggregates from the Repository first AFIK.

Would love if you could also contribute in your free time.

I have just updated it with Unit Of Work and change tracking

https://github.com/dasiths/NEventLite/blob/master/NEventLite%20Framework/Repository/ChangeTrackingContext.cs

Here’s a few ideas for you:

  • your domain models are the command handlers. I.e. there’s no need for boilerplate command handlers. Move concurrency checks and general error handling to your infrastructure. Send commands straight to your domain models.

Here’s another thought:

  • always create a snapshot. Infact, your default viewmodel for each domain model can be the snapshot. Think of the events as audit logging and signals to other parts of your domain (to update for example). If you follow this path you can drive your design into only domain models with snapshots, i.e. no other types of readmodels (except for advanced search - ElasticSearch, or other exceptional cases). This will simplify your application a lot!

Good luck!

/Daniel

"* always create a snapshot. Infact, your default viewmodel for each
domain model can be the snapshot. Think of the events as audit logging
and signals to other parts of your domain (to update for example). If
you follow this path you can drive your design into only domain models
with snapshots, i.e. no other types of readmodels (except for advanced
search - ElasticSearch, or other exceptional cases). This will
simplify your application a lot!"

No it won't. Snapshots have all the same versioning issues of storing
state. Small changes in domain require rebuilding all snapshots.

Ah, phrased it wrong. Meant to also say: only keep one snapshot. This is the key.