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.

1
2
3
4
5
6
7
8
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:

1
2
3
4
5
6
7
8
9
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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.

1
2
3
4
5
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.

1
2
3
4
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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, add TypedFactoryFacility and CommandFacility into the mix and start commanding yourself:

1
2
3
4
5
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.

Comments