This post has been imported from my previous blog. I did my best to parse XML properly, but it might have some errors.
If you find one, send a Pull Request.
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.
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
Interested in learning more about topics like this? Click here to join my newsletter. No spam. Meaningful content only.
Now, we need the aggregate base class to hold the capture the applied events.
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.
I really love the series. Recently I've stumbled upon Marten framework and I'd really love to see some guidelines like this tutorial, in relation to Marten - how to work with the inline projections etc. Any chances?by Michał Gajek at 2017-01-25 07:27:59 +0000
Thank you Michał for this positive feedback! I'm investing some of my OSS time in Marten nowadays as it's a truly outstanding library. I need to ask first: have you read official Marten's documentation related to Event Sourcing http://jasperfx.github.io/marten/documentation/events ?
I have a few topics for future series (Marten, is one of them), but haven't selected topic yet. I'll start a new one around mid February.by Szymon Kulec 'Scooletz' at 2017-01-25 10:32:06 +0000
Yes, I went through the entire documentation; while I find it quite comprehensive on technical details, it lacks some of the general design guidelines. Also the "aggregation" projection concept made me initially confuse it with an aggregate root, due to naming I believe. I like the idea of calling it "state" (or maybe I misunderstood something again? ;) )
Anyway, I'd be very glad to see the continuation of the series based on Marten, kind of "real-world" infrastructure stub/guidelines. For instance, how to properly design the AggregateRoot base class - so that the event is appended to the stream, and also to the current aggregate's state (projection?). Should the aggregate be injected with event dispatcher instance? Should it be responsible for loading it's current state (projection) when instantiated? ..etc.
I believe this would be extremely helpful, especially for beginners like me.
Looking forward to read more on this blog :)by Michał Gajek at 2017-01-25 14:20:33 +0000