CQS - your wish is my command

TL;DR: CQS is this cool principle of imperative computer programming (using statements to change a program's state). CQS isn't anything new, it's an old idea, so why write about it now? CQS is brand new to me, and I'm sure it will make my life (as a software developer) easier! So I'll start of telling about my ASP.NET Core implementation of CQS.


CQS, or command-query separation, is credited to Bertrand Meyer, and I'm not going to write more background about it, so go ahead and follow that link, if you need background.

I'm a big fan of OOP, and have the pleasure of working mostly with C#, which is a object-oriented language.

But for the last many years, most work is done transporting POCOs from layer to layer in the applications I build. There's not a lot of OOP in that. Yes, I use classes, methods, functions, attributes, interfaces, and from time to time, I even create an abstract class. But..

Most of my solutions involves working in ASP.NET MVC, so I create classes inheriting from the Controller class (MVC or WebApi), then I create some services (with lots of methods), maybe some repositories for working with the database (again, lots of methods), and lots and lots of classes (with properties) used for moving data in and out of the database and sending and recieving data from the client.

Luckily CQS is well-suited for OOP, so apart from hopefully helping me keep the complexity down in the applications I'm working on, it's also a step in the right direction for me, "back" towards a more OO approach in the solutions I work on.

Commands

CQS has commands and queries. Commands perform an action. So we'll start off with that. CQS also states that commands (or methods that are commands), should not return anything. That's for queries.

Show me the code

I've created a IMessage interface, you can do without this, but I'll leave it in for now.

public interface IMessage { }

And then the ICommand interface. Again I could leave this out, but it makes it a lot easier when creating the generic interface for the handlers in a bit.

public interface ICommand : IMessage { }

My example

I've worked a bit with a forum solution in the past, MVC Forum to be specific, and I'll use that as my example. A command in this application could be CreateNewTopicCommand or DeleteMessageCommand etc.

public class CreateNewTopicCommand : ICommand {
    public int ForumId { get; set; }
    public string Subject { get; set; }
    public string AuthorName { get; set; }
    // and lots more!?
}

Hm.. just another POCO. And now for the part that actually executes the command this, the command handler.

public interface ICommandHandler<TCommand> where TCommand : ICommand {
    void Execute(TCommand command);
}

So back to the CreateNewTopicCommand, we could (pseudo) implement a command handler like this:

public class CreateNewTopicCommandHandler : ICommandHandler<CreateNewTopicCommand> {
    protected readonly TopicRepository topicRepo;
    public CreateNewTopicCommandHandler(TopicRepository topicRepo) {
        this.topicRepo = topicRepo;
    }

    public void Execute(CreateNewTopicCommand command) {
        topicRepo.Create(command.ForumId, command.Subject, command.AuthorName /* etc etc */ );
    }
}

You can use a service instead of the repository, or a connection to the database, or whatever your flavor is.

This is all very simplified of course, but it should be enough to give you a good idea of some of the benefits. Just to mention one that springs to mind, testing.

So in a solution with a certain complexity, you can imagine the number of commands (and handlers) can quickly get quite large. So to avoid this becoming a problem, and to keep everything loosely-coupled, I'm of course using dependency injection. To avoid injecting a command handler per action in a controller, we're building a CommandDispatcher class for this. As my CQS package will not be tied to a particular DI framework, I'll just create an interface for this.

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

I've also implemented an abstract class for the dispatcher. This will probe the assemblies (with reflection) and locate the match between the type of the command and the command handler, pretty simple actually. With that cached, I can get the command handler that matches a command, so now all I need to inject in my controllers, are a CommandDispatcher instance.

public class TopicController : Controller {
    private readonly ICommandDispatcher cmdDispatcher;
    public TopicController(ICommandDispatcher cmdDispatcher) {
        this.cmdDispatcher = cmdDispatcher;
    }
    public ActionResult Create(NewTopic model) {
        if (ModelState.IsValid) {
            cmdDispatcher.Execute(new CreateNewTopicCommand { /* TODO */ });
            // ... Redirect to "create success page"
        }
        // ... Show errors
    }
}

Some simplified examples, but it should be enough to get an idea on what it is I'm trying to accomplish. You might feel it's a bit too simplified?

So how do we handle validation, other than the simple validation handled by MVC, client- and/or server-side? How do we handle permission checks, again other than the simple checks done by MVC?

We use the decorator pattern, but that will have to wait for another post.

Comments

Thank you for your comment! If it's not spam, it will be published shortly!

Your e-mail address will not be published. Required fields are market *

*

Copyright © 2015 by Steen F. Tøttrup. Powered by NBlogEngine by creativeminds & Romangie Theme.