OK, old thread, but one of the more recent on the subject.
I think this is a super important subject, don’t know if others do. My projects are constantly changing, evolving and improving. I rethink the events many times, and I do things that are essentially refuctors because everything would break if I would not adjust related parts of the system to the changes… (which can be alot of work, but is a must if previous solution was crappy).
Changing what the system needs from an already existing event, is a bit tricky. (The system depends on the events to transfer certain information).
Setting up new events + eventhandlers and keep the old ones around: I have thought that maybe just keep new eventhandlers in new files, and load them in to an internal list of the aggregate, as to not bloat down that file entirely. Amount of code wont be less, but it will be a little bit easier to keep things ordered. Really not a design solution, more about how to aid the brain in maintaining overview.
Translator/upgrader will blur the visual appearance of the code/system. Don’t know which takes less effort to not mess up.
Any how, let’s say I have event A. I happened to design it (and the system logic) wrongly, but it has it’s part to play. I just realised that for things to actually work I need to add some extra behaviour in the system around that event, i.e. both in the AR that raises it, and in the process that reacts to it (or in the other AR, don’t split hairs). How would that weak serialization be a solution in that case? The system will break when it tries to access properties in the old events, that were never populated at the moment of their inception. That’s what we have the translators for, no?
Creating a new event B on the other hand will require:
-
a command for the event
-
a command handler for the command
-
an eventhandler in the AR
-
an eventhandler in a processmanager that acts on other ARs as a result of the event
-
a router for the processmanager
-
possibly some handler in a read model for that event
-
probably some additional stuff I forget now
This is not hundreds of lines of codes, but still a few. It’s almost the same procedure for every new event.
Just adding one property to the event, would be so much easier. So setting up translators for every change then. That would eventually result in a range of translators, applying their changes one after another to the passingthrough events.
So event A goes through translator A-Z, each adding a property according to some new logic, that is written for the sole purpose of fetching that property value from somewhere (if possible) and populate the event with it.
If it was not possible to fetch that data (never stored and not possible to derive) the new behaviour must have protective logic to account for these missing values. Would bloat the code a little. I guess that’s a necessary tradeoff then.
Is this the end of the road? Or can this be solved in a better way?