Tuesday, November 14, 2017

Event Sourced Aggregates Part 4: Smart command handlers

In this fourth post in my series about event sourced aggregates I will continue work on the command handlers. In the 3rd post I did some cleaning up of the command handlers, cutting them down to very little code. In this post I will make the command handlers smart by moving domain logic from the aggregate to the command handlers.

Motivation

In the first and second posts of the series I outlined a typical C# implementation of event sourced aggregates and how that style of implementation leads to ever growing aggregates - every added features adds (at least) two methods to the aggregate: 
  • One for the domain logic. E.g. a 'ChangeUsername' method, that has whatever business logic there is around changing the username. If and when these methods decide a change to the aggregate state is needed they emit a domain event.
  • A 'When' method for any new events. The `When` methods perform all state changes on the aggregate.
The patterns I see in the implementations I come across is that there is a one-to-one correspondence between commands, command handlers and public domain logic methods on the aggregate. For example the pattern is that for a 'ChangeUsernameCommand' there is a 'ChangeUsernameCommandHandler' class and a 'ChangeUsername' method on the aggregate. I took almost all the plumbing out of the command handler in the last post and essentially left it at this:


which invokes the 'helper.Handle' method to get all the plumbing done and then calls the 'ChangeUsername' method to get the domain logic done. So in essence the command handler just delegates to the aggregate, but isn't the responsibility of the command handler to ... handle the command? I think it is. And handling the command means running the domain logic, so let's move that logic from the aggregate to the command handler.

Smart command handlers

In the second post I introduced the 'ChangeUsernameCommand` and the associated command handler and methods on the aggregate. In particular this `ChangeUsername` method on the aggregate:



which implements the domain logic for changing username. That is the logic I want to move to the command handler.
Moving the domain logic straight over the command handler, changes the `Handle` method on the command handler to this:



Now the command handler contains the logic for handling the command. Note that now the command handler also emits domain events - on line 7. This makes sense since this is still event sourced, so changes to the aggregate state are still done through events. The rest of the mechanics around events remain unchanged: The `Emit` method on the base aggregate still calls the 'When' method for the event and stores the event to the list of new events on the aggregate. Saving the aggregate still means appending the list of new events to the event store, and getting the aggregate from the 'AggregateRepository' still means reading all the aggregates events from the event store and replaying each one.

Having moved the domain logic out of the aggregate I have a slimmer aggregate, that only has the state of the aggregate and the 'When' methods. In the next two post I slim down the aggregate even further by moving the 'When' methods out.

The complete code for this post in this branch.

Monday, November 6, 2017

Event Sourced Aggregates Part 3: Clean up command handlers

This is the 3rd part of my series about event sourced aggregates. In the first post I outlined a typical implementation of event sourced aggregates, and in the second post I showed how that implementation leads to aggregates that grow bigger and bigger as features are added to the system. In this post I will clean up the command handlers from the previous post by moving some repeated code out them to a new abstraction. In the coming posts I will refactor between the command handlers, aggregates and event handlers to arrive at a design where the aggregate does not grow.

Repeated code in command handlers

In the last post we looked briefly at this implementation of a command handler:


Looking at the above the code at line 20 is - in a sense - where the ChangeUsernameCommand the is handled, because that is the only line that is about changing a username. All the other code in the command handler is about infrastructure; loading the aggregate, saving the aggregate and dispatching events. Moreover the code for loading and saving aggregates as well as the code for dispatching will be repeated in every command handler

Introducing a helper

To get past that repetitiveness and to cut back on the amount of infrastructure code in the command handler, we introduce this helper, where the loading of the aggregate, the saving of the aggregate and the dispatching of events is done:


The idea behind the CommandHandlerHelper is that the concrete command handler calls the Handle method with a handlerFunc, that does the business logic bit of the command handler. The handlerFunc is called at line 18, so the helper makes sure the infrastructure code is done in right order in relation to the business logic.

Cleaner command handlers

With the CommandHandlerHelper in place the ChangeUsernameCommand can be rewritten to use it like this:

This is a good deal simpler than the command handler code at the start of the post.


That's it for now. With this clean up in place we set for the next steps:
  • Make the command handlers smarter
  • Make the aggregate anemic in a naive way, leaving a stable aggregate, but introducing a new Open/Closed violation
  • Make the aggregate anemic, events (a little) smart, and solve the Open/Closed violation

Tuesday, October 31, 2017

Event Sourced Aggregates Part 2: Where the mess starts

In the first post in this series I outlined a typical C# implmentation of  event sourced aggregates. In this post we add a second feature to the example from the first post. In doing so I wish to illustrate how that typical implmentation leads to violation of Open/Closed principle and ever growing aggregates.

The second feature

Once we have the code from the first post in place - that is: The infrastructure for sending commands to aggregates, raising events from aggregates, saving events and replaying events - and need to add a second feature, the way to do it is (to some extent) as outline in the first post: 
  1. Send a new type of command
  2. Implement a command handler for the new command
  3. Implement a new method on the aggregate with the new domain logic
  4. Emit any new events needed
  5. Implement new When methods for any new event types
Let's say we want to be able change a users username.
The command and the sending of of that command looks like this:



That's pretty straight forward and not too interesting, so let's move on to the command handler:



That's also pretty straight forward, but a little more interesting: Most of the the command handler code is something that will be repeated in all commands handlers. We will deal with this in the next post, where that repetition is pulled out into a helper class.
The next step is changes to the aggregate, where this is added:



This is still pretty straight forward. In fact everything needed to add this new feature was straight forward, so that is a good thing. The problem lies in the last two methods, the ones added to the aggregate.

Problem: An Open/Closed Principle violation

The aggregate just grew. In order to support changing the username we added 2 methods to the aggregate. That violates the Open/Closed principle, which indicates that it is a potential problem. In my experience, it quickly becomes a real problem because the aggregate grows relatively quickly and eventually becomes big and complicated, just like any other class that grows monotonically.

That's it for now. The next posts will:
  1. Make the command handlers smarter and clean up some repetitiveness
  2. Make the aggregate anemic in a naive way, leaving a stable aggregate, but introducing a new Open/Closed violation
  3. Make the aggregate anemic, events (a little) smart, and solve the Open/Closed violation