Command query separation with ASP.NET MVC

I have been struggling for some time to find an application architecture for ASP.NET MVC that both respects SOLID principles and is also quick and simple to use. Is the command query separation (CQS) pattern the answer?

The simplest model is the repository pattern, you create a repository for each entity type and you expose these to controllers as constructor dependencies.

publc class MyController : System.Web.Mvc.Controller
{
    protected readonly IRepository _repository;

    public MyController(IRepository repository)
    {
        _repository = repository;
    }
}

However, this approach soon starts to get unwieldy when you get into real world projects as you quickly build up dependencies on several repositories. Even if we are being disciplined about separating responsibilities across different controllers, it is likely that you will need to touch at least two or three repositories. Does this really matter? Yes, because when it comes to writing unit tests, adding extra dependencies makes it more time consuming to write each test, and this deters you from doing good unit testing.

One route to solving this problem is to roll these dependencies up into a service. This keeps things simple at the controller level, but really only pushes the problem up a layer. The services get more and more bloated over time, and rack up the dependencies themselves. We are still breaking SRP and making it hard to unit test.

I first came across CQS in the CodeCampServer example application from Jeffrey Palermo, but I have also seen it in S#arp Architecture. Both projects appear to have run out of steam a few years ago, but demonstrated some interesting ideas.

The CQS principle states that every method should either be a command that performs an action or a query that returns data, not both. In some architectures this separation is driven by the desire to separate the reading and writing of data into different systems using messaging and events but I don't want to focus on these more complex architectural systems.

In a typical implementation the pattern is captured via an interface like this:

public interface ICommandHandler<TCommand>
{
    void Execute(TCommand command)
}

So each command handler is a separate class instantiating this interface, and there is a one-to-one relationship with a unique command message class. This approach immediately provides several benefits.

The bit that people start to balk at is the fact that we have no return type. In strict implementations this is for scale out reasons and wanting to separate reads from writes. Personally this is a good approach to take if it works, and I don't think it is too difficult to develop UIs that work with this asynchronous approach, but I'm not averse to using a return type if it works for a given application. We can tweak as follows:

public interface ICommandHandler<TCommand>
{
    CommandResult<TResult> Execute(TCommand command)
}

I think the command side of things is pretty strong, and you can take away some of the pain of having to create so many classes through automation using your favourite IoC container. I'll try and find some time to document how we've done it soon. The interesting part is ironically the query side which you think would be simple.

There is nothing to stop you simply switching back to using repositories/services in the controller, strictly speaking this is separate from commands but would lead back to the limitations outlined earlier. It also feels wrong to me as it gives the controllers too many responsibilities. So if we reject this we need some form of query objects. In S#arp Architecture they suggest that such objects should live at the presentation layer. I can see the motivation for this, queries are about viewing information, and many concerns around the format and nature of these queries will be driven by presentational concerns such as pagination. It definitely feels wrong to be putting pagination logic into domain level libraries. However, this then requires them to "infect" the presentation layer with infrastructure concerns:

public class ProductListQuery : NHibernateQuery, IProductsListQuery
{
    public IPagination<ProductViewModel> GetPagedList(int page, int size)
    {
        ...
    }
}

Now there are some intelligent programmers who have argued that there is nothing wrong with making direct use of your persistence framework. Personally I prefer to keep my options open by not being quite so explicit. I suggest the following approach:

public interface IQuery<TResult> { }

public interface IQueryHandler<TQuery, TResult> where TQuery : IQuery<TResult>
{
    TResult Handle(TQuery query);
}

You can then implement a handler class that can be exposed to your persistence framework:

public class ProductListQueryHandler : IQueryHandler<GetProductQuery, PagedList<Product>>
{
    public PagedList<Product> Handle(GetProductQuery query)
    {
        ...
    }
}

Again, this can all be wired up using your IoC container. I appreciate that it does involve some slight overhead but on balance I think that is worth it for the improved unit testability.