In the last post we did a TDD walk through building the application but we didn’t really get into the event sourcing side of things, which was the original intent of this series.
I only recently read about Event Sourcing through the book Understanding Eventsourcing by Martin Dilger. It goes into a lot of detail, including event modelling, which was the inspiration of this little project/blog series.
The basic idea is that we aren’t making updates and saving our domain entities using property changes directly but instead, we persist events that happen to our object. When it’s time to retrieve the object, we retrieve all the events specific to that entity and rebuild its current state accordingly.
The key advantage I see is that your actual Domain Model doesn’t need to be correct when you first implement because you’re not storing your model, instead you’re storing the events. As long as you store your events with the necessary data, you will be able to ‘rehydrate’ your object using it. And if a future feature requires a new property to be set, just create a new event that includes the new data you need.
I recorded my process because i was hoping to then take screenshots after for the blog. It’s hard to write code and then write the blog post at the same time. But now I’m too lazy to go back and watch through it.
Here it is future me, sped up 3x at least:
Aside: First time I learned about it, my mind was blown, more because of the parallels to the real world. But this feels like a separate blog post of its own…

If we recall the Event Model for the slices we are working on, two events happen on the Individual.
The tests I created look like this. I ended up adding a status so I could easily verify which stage the individual is in.

Notice in the second tests, we pass a list of previous events to the constructor in order to ‘rehydrate’ the domain model. When we start to persist these, it will come in handy. The idea is we will be retrieving the events for this individual from a repository, and by applying them one by one, the instance of the Individual arrives at its current state.
The Domain object is as follows, we have an Individual with two properties, email and status. The individual can Register Interest and Confirm Registration as currently defined in our event model. These are the only public interfaces our object has.

The methods are commands on the object. If the command is considered successful, an event is applied. It’s at this point we can have the aggregate enforce any invariants or consistency rules that it needs to maintain in order to be in a valid state. In the ConfirmRegistration case, we say the individual needs to be in InterestSubmitted status in order to confirm.
After all the checks, only then do we apply the event.

In the next post, we will look at how to persist and then retrieve our objects.
The latest code can be found here
Leave a comment