Brownfield CQRS part 4 – Command Dispatcher

In the first two posts I talked about commands and command handlers. Now we need to wire them up to invoke them from your service endpoint.

Command Dispatcher

When a command arrives, you simply look up the corresponding handler from your IoC container and invoke it. This responsibility is delegated to a command dispatcher object:

public interface ICommandDispatcher
{
    void Dispatch<T>(T command) where T : ICommand;
}

public class CommandDispatcher : ICommandDispatcher
{
    private readonly IWindsorContainer container;

    public CommandDispatcher(IWindsorContainer container)
    {
        if (container == null) throw new ArgumentNullException("container");
        this.container = container;
    }

    public void Dispatch<T>(T command) where T : ICommand
    {
        if (command == null) throw new ArgumentNullException("command");

        var handler = container.Resolve<ICommandHandler<T>>();
        ErrorIfNoHandlerForCommandFound(handler);

        handler.Handle(command);
    }

    private static void ErrorIfNoHandlerForCommandFound<T>(
        ICommandHandler<T> handler) where T : ICommand
    {
        if (handler == null)
            throw new NoHandlerForCommandException(typeof(T));
    }
}

Then we simply inject the command dispatcher into the WCF service and invoke it whenever a command is received:

[ServiceBehavior]
public class BookingService : IBookingService
{
    private readonly ICommandDispatcher commands;

    [OperationContract]
    public void BookTable(BookTableCommand command)
    {
        if (command == null) throw new ArgumentNullException("command");
        commands.Dispatch(command);
    }
}

Many of you will note that this is very similar to Udi Dahan’s Domain Events aggregator — the only major difference is CQRS commands are only ever handled by one handler, where domain events are broadcast to anyone who’s listening.

Scaling out

Note this is a synchronous command dispatcher — commands are handled as soon as they arrive. An asynchronous/high-volume system may simply put them in a queue to be executed later by some other component.

Final thoughts

This really is a very introductory series to refactoring an existing application to move towards CQRS. We haven’t even touched on the main goal of CQRS yet — all we’ve done is put clear command/query contracts between our client and server.

It may not sound like much, but doing so allows us to mask non-CQRS components in our system — an anti-corruption layer of sorts — and allows us to proceed refactoring them internally to use different models and storage for commands and queries.

10 thoughts on “Brownfield CQRS part 4 – Command Dispatcher

  1. There are actually many reasons to support a pipeline of command handlers for a given command. One of them is the ability to factor out things like Authentication and Authorization into generic command handlers – that of course requires the ability have polymorphic dispatch of commands to handlers. Other scenarios include setting up an ordered pipeline of handlers, first having all validation handlers run, each having the ability to stop the pipeline (Bus.DoNotContinueDispatchingCurrentMessageToHandlers()), and after that having the command handlers which actually do the work.

    Hope that makes sense.

  2. Udi: Yeah definitely. Logging, auditing and persisting commands too if that’s a requirement.

    But Bus.DoNotContinueDispatchingCurrentMessageToHandlers() – does that mean you are distributing these preprocess pipeline steps over a bus, request/response style?

  3. Are command handlers allowed to directly call other command handlers (direct or via dispatcher?). For example, I have a ChangePasswordCommandHandler and one of the args in the command is ‘OldPassword’. So, I was wondering if it is ok for the handler to delegate out to the ValidateUserCredentialsCommandHandler or should I just refactor some of the logic into another service.

    Im running into an issue because I have transaction-per request setup and this is causing multiple transactions to open.

  4. @Marco: I would use a preprocessor/interceptor to validate commands (and reject them) before they get to the command handler.

  5. Ok, fair enough. Im still tryng to decide if handlers live in isolation or can communicate with each other. I have two handlers, ChangePasswordCommandHandler and ResetPasswordCommandHandler. It would make sense to have the reset handlers call out to the change password, but now they are coupled.

    thoughts?

  6. @Marco make your IPasswordService reusable, but I think it’s best to keep the command-handlers as outer-level entry points (called only by external callers) rather than making commands and calling each other.

  7. I’m a little late but i’m starting to form different opinions the more I think about this type of situation from this question:
    “Are command handlers allowed to directly call other command handlers (direct or via dispatcher?). For example, I have a ChangePasswordCommandHandler and one of the args in the command is ‘OldPassword’. So, I was wondering if it is ok for the handler to delegate out to the ValidateUserCredentialsCommandHandler or should I just refactor some of the logic into another service.”

    And Richard’s response:

    “@Marco: I would use a preprocessor/interceptor to validate commands (and reject them) before they get to the command handler.”

    I think that in this situation, the ChangePasswordHandler should indeed cause other handlers to process, however it should not be calling those other handlers directly. Within ChangePasswordHandler, or the method that changes the password, a PasswordChangeEvent should be raised, and any other handlers that are responding to that event should handle PasswordChangedEvent accordingly.

Comments are closed.