In the last entry we changed the Payment aggregate to modify state by raising events. The events weren’t captured though. In this post, we’ll change the aggregate to enable recording of these changes.
All entries in this series:
- 1 – back to foundations
- 2 – aggregate sketch
- 3 – first implementation
- 4 – finding events
- 5 – applying events
- 6 – recording aggregate
- 7 – the fully functional end
The easiest way to capture events is to make them pass one additional method. We could provide one Apply method in the aggregate itself that beside applying the event it would. To make it usable in all the aggregates we could create a base class that would have this method. Let’s apply it to the Payment first
Now, we need the aggregate base class to hold the capture the applied events.
The base aggregate
We use the base class to track the changes and provide one point of entry to applying events. The dynamic is used to implement it fast. If you wanted to optimize, you could remove it by writing a custom dispatcher that calls directly a method from the derived aggregate.
When the action ends, a handler executing it calls GetEvents and gets all the events that were raised during this session. This enables you to write simple tests with a Given-When-Then approach and easily extract the changes for persistence purposes. On the other hand, we introduced the base class for the aggregate. What could be done more?
By introducing a base AggregateRoot class we enabled capturing all raised events. This simplified a little bit Payment aggregate itself, but introduced the base class. It’s time to move to the final part where we make it functional removing some code we’ve written so far.