Domain Driven Design: Commands and Events Handlers different responsibilities

Event Sourcing

“Commands have an intent of asking the system to perform an operation where as events are a recording of the action that occurred…”
Greg Young, CQRS Documents Pag. 26

In this post I’d like to state something that I’ve just recalled from a Greg Young’s video. When I started creating an aggregate root I often ask myself… where do I put this logic? where do I have to set these properties? Is the Command or the Domain Event Handler responsible?

As we know, an aggregate root can be considered a boundary for a relevant business case. The public interface of an aggregate exposes behaviours and raises events.

Commands and Events responsibilities

Commands and Events responsibilities

With this in mind, when we design an aggregate root, we start adding behaviours/commands to it and then apply events. The following is a list of what a Command and a Domain-Event handler can and cannot do.

A Command handler is allowed to:

  • Throw an exception if the caller is not allowed to do that thing or passed parameters are not valid
  • Make calculations
  • Make a call to a third party system to get a state or any piece of information

A Command handler is not allowed to:

  • Mutate state (state transition in commands can’t be replayed later applying events)

It behaves like a guard against wrong changes.

A Domain Event Handler is allowed to:

  • Mutate state

A Domain Event Handler is not allowed to:

  • Throw an exception
  • Charge your credit card
  • Make a call to a third party system to get a piece of information
    (logic here can be replayed any┬átime… for example your card can be charged any time you replay events)

They apply the required changes of the state. No validation, no exceptions, no logic.

For example, if we have a command handler method called Deposit that receives an amount of money and updates the balance, we can implement a simple algorithm in the method and raises an event MoneyDeposited with the result of the calculation and any other information that we want to keep stored in our event store.

Example:

public void Deposit(decimal quantity, DateTime timeStamp, Guid transactionId, bool fromATM = false)
{
  if (quantity <= 0)
    throw new Exception("You have to deposit something");
  var newBalance = balance + quantity;
  RaiseEvent(new MoneyDeposited(newBalance, timeStamp, ID, transactionId, fromATM));
}
private void Apply(MoneyDeposited obj) 
{
  balance = obj.NewBalance;
}

Hope this helps

CQRS WITH EVENT SOURCING USING EasynetQ, EVENT STORE, ELASTIC SEARCH, ANGULARJS AND ASP.NET MVC

Event Sourcing

“The magic for a developer is doing something cool that no one else can understand” (myself few minutes ago).

The first step into this maze of cool messaging terms and tools left me with the feeling that most of them are not really relevant. After years of studying and practising, all these messaging and service oriented concepts melted with DDD and CQRS are making a lot of sense.
In this post I’d like to take out of my personal repository something that helped me in that journey.

Some time ago I read a very interesting blog post by Pablo Castilla https://pablocastilla.wordpress.com/2014/09/22/cqrs-with-event-sourcing-using-nservicebus-event-store-elastic-search-angularjs-and-asp-net-mvc/
I started studying it and I found it simple and complex enough to be taken as base template for my DDD + CQRS + Bus projects. Unfortunately after a while the trial version of NServiceBus expired on my home PC and then I decided to change the bus infrastructure from NServiceBus/MSMQ to EasynetQ/RabbitMq. Everything else is the same as in the original blog by Pablo except that I have updated all projects and libraries to the latest versions.

The solution’s work flow…

Bus and Event Sourcing

Bus and Event Sourcing

When you switch from a Bus generic framework like NServiceBus to a Bus Specific tool like EasynetQ a lot of configuration settings disappear.

For example you don’t need any more EndPoint config classes implementing those curious interfaces like IWantCustomInitialization
If you decide to adopt a Broker based solution you don’t have to waste hours and set every aspect of all little nice features that NServiceBus provides using xml config files or its fluent configuration. Instead you can immediately start to be productive and without paying much attention to configuration, you can start coding your app features and you publish and subscribe messages. Pay attention to some of the bad side effects of message patterns and take care of problematic scenarios if you have to. RabbitMq is a mature and solid infrastructure piece of software and it offers many solutions. EasynetQ is a little easy to use tool that offer a quick and clean Publish Subscribe mechanism.

Another consideration on NServiceBus here is that using Event Store you can rely on a feature built in it that allows you to manage long running processes. In this way you don’t need one of the nice features that NServiceBus provides called SAGA http://docs.particular.net/nservicebus/sagas/
Instead of using a Saga with NSB that finally is a class that stores everything happening around a process in a single storage like SqlServer with Event Store, is like defining an Aggregate that contains a stream of events and define projections running continuously and that allows you to react when something happens.

Said that, NServiceBus is an elegant library which is full of message features that can solve a lot of distributed architecture problems.

This is the code: https://github.com/riccardone/CQRS-NServiceBus-EventStore-ElasticSearch

References:
EasyNetQ
http://easynetq.com/

RabbitMQ
https://www.rabbitmq.com/