I command you

Standard

Setup

Today we are going to talk about CQS (Command Query Separation). In this blog post i will focus on the command part. Commands are simple objects that instruct our application to do something. I will show you the most simple implementation possible, combined with the power of Castle Windsor, which will act as our command handler registry. Let’s show the basic duo, namely our command and it’s respective handler.

 public interface ICommand
 {
 }

 public interface ICommandHandler<T> where T : ICommand
 {
    void Handle(T command);
 }

The ‘ICommand’ interface acts as a marker interface to mark all of our commands in our code base. Let’s take the example model from my previous blog post as a starting point for our first command:

public class MoveCustomerCommand : ICommand
{
  public int CustomerId { get; set; }
  public string Street { get; set; }
  public string StreetNumber { get; set; }
  public string PostalCode { get; set; }
  public string City { get; set; }
  public string Country { get; set; }
}

And it’s dedicated handler:

public class MoveCustomerCommandHandler : ICommandHandler<MoveCustomerCommand>
{
    private readonly ICustomerRepository _customerRepository;
    private readonly IUnitOfWork _unitOfWork;

    public MoveCustomerCommandHandler(ICustomerRepository customerRepository
                                      , IUnitOfWork unitOfWork)
    {
        _customerRepository = customerRepository;
        _unitOfWork = unitOfWork;
    }

    public void Handle(MoveCustomerCommand command)
    {
        Customer existingCustomer = _customerRepository.GetById(customer.Id);
        if (existingCustomer == null) 
           throw new InvalidOperationException("Customer does not exist");

        var newAddress = new Address(customer.Street
                                     , customer.StreetNumber
                                     , customer.PostalCode
                                     , customer.City
                                     , customer.Country);

        existingCustomer.Move(newAddress);

        _unitOfWork.SaveChanges();
    }
}

Infrastructure

Bus

The Bus acts as the primal communication point in our application, it’s responsibility is too send command’s, directly we add a single command send and a multiple command send, so we can use this later as a facade for our unitofwork/transaction setup (The more reactions i get to this post, the more i will invest in diving into the nitty bitty details ;))

public interface IBus
{
    void Send(ICommand command);
    void Send(ICommand[] commands);
}

Dispatcher

The dispatcher’s primary role is execute the handler of the command given. Later we could use this to do for instance validation on our commands.

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

Show me the code

A possible bus implementation, that will invoke the dispatcher’s generic dispatch method:

public class DispatchingCommandBus : IBus
{
    private readonly ICommandDispatcher _dispatcher;

    public DispatchingCommandBus(ICommandDispatcher dispatcher)
    {
        _dispatcher = dispatcher;
    }

    public virtual void Send(ICommand command)
    {
        if (command == null) return;

        MethodInfo method = typeof (ICommandDispatcher).GetMethod("Dispatch");
        MethodInfo generic = method.MakeGenericMethod(command.GetType());
        generic.Invoke(_dispatcher, new object[] {command});
    }

    public void Send(ICommand[] commands)
    {
        if (commands == null) return;

        foreach (ICommand command in commands) Send(command);
    }
}

And an example implementation of our dispatcher, which will use a commandhandler factory to get the respective handler:

public class DirectExecutingCommandDispatcher : ICommandDispatcher
{
    private readonly ICommandHandlerFactory _factory;

    public DirectExecutingCommandDispatcher(ICommandHandlerFactory factory)
    {
        _factory = factory;
    }

    public void Dispatch<T>(T command) where T : ICommand
    {
        ICommandHandler<T> handler = _factory.CreateHandler<T>();

        try
        {
            handler.Handle(command);
        }
        finally
        {
            _factory.Release(handler);
        }
    }
}

The ‘ICommandHandlerFactory’ is fully implemented by Castle Windsor’s TypedFactory facility, and if you are wondering why the release code, please read my post about understanding memory leaks with Castle Windsor.

The commanding facility

All necessary registration’s nicely molded into a custom facility :

using System.Linq;
using Castle.Core.Configuration;
using Castle.Facilities.TypedFactory;
using Castle.MicroKernel;
using Castle.MicroKernel.Facilities;
using Castle.MicroKernel.Registration;

namespace Sapphire.Commands
{
    public class CommandingFacility : IFacility
    {
        public void Init(IKernel kernel, IConfiguration facilityConfig)
        {
            AssertFacility<TypedFactoryFacility>(kernel);

            kernel.Register(Component.For<ICommandHandlerFactory>().AsFactory());

            kernel.Register(Component.For<ICommandDispatcher>()
                                     .ImplementedBy<DirectExecutingCommandDispatcher>()
                                     .LifestyleTransient());

            kernel.Register(Component.For<IBus>()
                                     .ImplementedBy<DispatchingCommandBus>()
                                     .LifestyleTransient());
        }

        public void Terminate()
        {
        }

        private void AssertFacility<T>(IKernel kernel)
        {
            if (kernel.GetFacilities().Any(f => f is T)) return;
            throw new FacilityException(string.Format("CommandingFacility is dependent on {0}", typeof (T).Name));
        }
    }
}

Wrapup

So to use this code, just register all of your commandhandlers, best with a lifestyle of transient, and add TypedFactoryFacility and CommandFacility into the mix, and start commanding away ;)

var container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.AddFacility<CommandingFacility>();

//Register all your command handlers
...

The code, and the supplementary unit tests, are available on Github.

11 thoughts on “I command you

  1. Is there a more efficient way to declare all of your public variables, rather than repeating “public” on every line? Not criticizing, just trying to learn! :)

  2. Agatha pretty much has all of this already, except that it doesn’t have an explicit separation between Queries and Commands. But the handlers, dispatching and IoC registration… it’s all there and you can use it in-process ;)

    • Davy, although i don’t mind you advertising Agatha on my blog :P, i never left the process and this post is just here to show a clear and simple way of doing it, takes about 25 lines of code :)

      • not really trying to advertise it, I don’t even work on it anymore :)

        I’m just seeing a lot of examples like this lately, and hearing about people building this stuff themselves for their projects while it’s all out there already. Just kinda seems like a waste, that’s all.

      • I was not trying to invent the wheel again, just blogging about a simple way of handling commands, which I pretty much use myself in smaller projects, that don’t need the wcf bloat ware layer. But enough said I got your point of view ;) remember that I am again in a project where the manager pattern is king so bare with me :)

      • for the record, i wouldn’t recommend WCF to anyone again either… again, it’s just the in-process model of Agatha that can do what you’re blogging about… the whole WCF thing, even I’d wish that never happened ;)

  3. Cal

    Good article. I’ve been waiting for these posts since looking through your Nebula project on Github. Are you going to do posts on all the concepts from the Nebula/Sapphire project?

  4. Cal

    Just more posts on CQS and eventing. How you use them and also where and why. Will you be updating the Sapphire project with examples like above?

    Anyway great sample project I use Nebula when people ask me where they can find an example of good code. :)

What do you think ?

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s