.NET Backend

CQRS/ES #5 Command Bus and Event Bus

All right, after a few short breaks, I’m finally ready to continue our journey, during which we discover Command Query Responsibility Segregation pattern along with Event Sourcing. In a previous part, we discovered the role of events and ES in our application and to be honest we’re almost done! But before that, we need to focus a little bit on transporting our commands and events. That’s why today’s post will be dedicated the buses. Okay, let’s start!

 

RabbitMQ and EasyNetQ

To accomplish our task, we need to install some queuing mechanism in our OS and a project. First, we are going to use RabbitMQ which is one of the most popular messaging built on top of the Erlang (programming language). The movie below shows the exact steps you should follow in order to install that on your machine:

 

 

Having the RabbitMQ, we need to use some API in ours .NET project to communicate with the queues. There are few of them, but the one that I’d recommend is EasyNetQ. Before we go any further, I just want to mention that this API doesn’t support the .NET Core yet. If you’re running your CQRS application on .NET Core you need to choose another library (e.g. RestBus).

 

Implementing Event Bus

Okay, let’s start with the EventBus. As we’ve already know our bus should do two things. First is finding a proper event handler to pass the event. Second is the queuing mechanism. The code below shows the implementation of the EventBus class using the EasyNetQ API:

 

public class EventBus : IEventBus
{
    IBus Bus { get; }
    IEventBusExecutor EventBusExecutor { get; }

    public EventBus(IEventBusExecutor eventBusExecutor)
    {
        EventBusExecutor = eventBusExecutor;

        Bus = RabbitHutch.CreateBus("host=localhost");
        Bus.Receive(nameof(EventBus), (IEvent @event) =>  EventBusExecutor.ExecuteAsync(@event));
    }

    public async Task SendAsync<TEvent>(TEvent @event) where TEvent : class, IEvent =>
        await Bus.SendAsync(nameof(EventBus), @event);
}

 

As you can see, there’s not so much code but even though we deserve some explanation here. The first thing we did is a creation of the bus using the static method delivered by IBus interface. Next line defines what action should be executed when the new event will bu pet on the bus. In our case its’s ExecuteAsync method of the EventBusExecutor object. The SendAsync method on the bottom is nothing more than just putting a received event on the bus. Well, that wasn’t hard, was it? But still, we have no idea what the EventBusExecutor is? Here’s the code:

 


public class EventBusExecutor : IEventBusExecutor
{
    IEventHandlerExecutor EventHandlerExecutor { get; }

    public EventBusExecutor(IEventHandlerExecutor eventHandlerExecutor)
    {
        EventHandlerExecutor = eventHandlerExecutor;
    }

    public async Task ExecuteAsync(IEvent @event)
    {
        var eventType = @event.GetType();
        var executorType = EventHandlerExecutor.GetType();

        await (Task) executorType.GetMethod(nameof(IEventBusExecutor.ExecuteAsync))
            .MakeGenericMethod(eventType)
            .Invoke(EventHandlerExecutor, new[] { @event });
    }
}
public class EventHandlerExecutor : IEventHandlerExecutor
{
    ICustomDependencyResolver CustomDependencyResolver { get; }

    public EventHandlerExecutor(ICustomDependencyResolver customDependencyResolver)
    {
        CustomDependencyResolver = customDependencyResolver;
    }

    public async Task ExecuteAsync<TEvent>(TEvent @event) where TEvent : class, IEvent =>
        await CustomDependencyResolver.Resolve<IEventHandler<TEvent>>().HandleAsync(@event);
}

 

That might look kinda weird, am I right? But when you look closely it’s just invoking the ExcecuteAsync method of the EventHandlerExecutor object. The reason we had to use reflection for that purpose is the fact that we wanted to create a one, universal method for every single event in our system. So, to make this possible we had to use the general type in a parameter (which is IEvent) and then in the runtime we need to check what is the exact type of each received event and invoke the generic method. I hope that’s clear 🙂 The only thing we need to explain now is EventHandlerExecutor class. In a nutshell, it’s factory (using Autofac dependency injection container) which resolves the proper event handler and executes the HandleAsync method on it. That’s why it’s called Executor, not the Factory 😀 I know that all of this code may confuse you, so I created a simple sequential diagram to make it clear:

 

diagram

 

Implementing Command Bus

The CommandBus looks almost identical to EventBus. The implementation looks as follows:

 


public class CommandBus : ICommandBus
{
    IBus Bus { get; }
    ICommandBusExecutor CommandBusExecutor { get; }

    public CommandBus(ICommandBusExecutor commandBusExecutor)
    {
        CommandBusExecutor = commandBusExecutor;

        Bus = RabbitHutch.CreateBus("host=localhost");
        Bus.RespondAsync<ICommand,IHandleResult>(commandBusExecutor.ExecuteAsync);
    }

    public async Task<IHandleResult> SendAsync<TCommand>(TCommand command) where TCommand : class, ICommand =>
        await Bus.RequestAsync<ICommand, IHandleResult>(command);
}

public class CommandBusExecutor : ICommandBusExecutor
{
    ICommandHandlerExecutor CommandHandlerExecutor { get; }

    public CommandBusExecutor(ICommandHandlerExecutor commandHandlerExecutor)
    {
        CommandHandlerExecutor = commandHandlerExecutor;
    }

    public async Task<IHandleResult> ExecuteAsync(ICommand command)
    {
        var commandType = command.GetType();
        var executorType = CommandHandlerExecutor.GetType();

        await (Task) executorType.GetMethod(nameof(ICommandHandlerExecutor.ExecuteAsync))
            .MakeGenericMethod(commandType)
            .Invoke(CommandHandlerExecutor, new[] { command });

        return new HandleResult(true);
    }
}
 public class CommandHandlerExecutor : ICommandHandlerExecutor
 {
     ICustomDependencyResolver CustomDependencyResolver { get; }

     public CommandHandlerExecutor(ICustomDependencyResolver customDependencyResolver)
     {
         CustomDependencyResolver = customDependencyResolver;
     }

     public async Task ExecuteAsync<TCommand>(TCommand command) where TCommand : class, ICommand
         => await CustomDependencyResolver.Resolve<ICommandHandler<TCommand>>()
             .HandleAsync(command);
 }

 

The only difference is that instead of using SendAsync method we used a RequestAsync which allows us to return a result to a Web API controller. Why is that important? Well, mostly because somehow we have to inform a user if validation of his command would fail or some code would fail before persisting his data into Event Store. But how do we return a result of HandleAsync which has a Task return type?  Remember that our Validate method inside each command handler throws an exception if something goes wrong. The same thing happens inside the Event Store and Domain Object. So, all we need to do is to surround execution of HandleAsync with try-catch and check whether it catches any exception. If not – we will return a Succeed result. Otherwise, we will return a Fail result. To keep the code clean I’d recommend using AOP for that purpose. If you’re not familiar with that concept, here is my other article about that 🙂 The code below shows the implementation of our simple aspect and its registration in Autofac module:

 


public class HandleResultAspect : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        try
        {
            invocation.Proceed();
        }
        catch (Exception exception) when((exception.InnerException as AwesomeCalendarException) != null)
        {

            invocation.ReturnValue = new HandleResult(false);
        }
    }
}

containerBuilder.RegisterType<CommandBusExecutor>().As<ICommandBusExecutor>()
                .EnableInterfaceInterceptors()
                .InterceptedBy(typeof(HandleResultAspect));
 
            
 
containerBuilder.RegisterType<HandleResultAspect>();

 

That’s it! Now if something would go wrong inside the Command Handler (or later), our aspect will catch the exception and set a proper result which lately will be passed to a Web API Controller. Here’s the sequential diagram for the whole process:

 

diagram2

 

Conclusion

As I wrote – we’re almost done! In the next episode (which will be the last one) we’ll implement the event handlers and the read side of our application! Remember that the whole project is available for you on Github (if you’d like to contribute, go ahead). I also encourage you to follow me on Twitter or Facebook just not to miss new posts on my blog!