In this post I'll show how easily you can implement the Command-part of CQRS in your application. If you don't know what CQRS (or Command Query Responsibility Separation for "short") is, you can read about it over at Martin Fowler, but the short story is that you want to separate the read and write parts of your application by keeping your reads away from the domain model. I won't go into detail on CQRS as a whole, but show how the Command-part can be implemented, and give some pointers along the way.
Disclaimer: This is not some invention by me. The code I'm presenting is written by me, but inspired by the work of others. I'm not taking credit for this approach, but simply conveying the principle :)
If you're working with Commands on a client or server-tier only you should check out my colleague Haralds post on Explicit error handling in commands also.
Requirements first
If you read my post on Domain Events (which will complement the result of this post real nice), you might remember how I started off by writing the code that I envision in my calling app. So let's start the same way.
I'm going to need some sort of executor that can execute my commands. Let's call that ICommandExecutor for now, and build out an interface:
ICommandExecutor executor; CommandResult result = executor.Execute(new SomeCommand());
This should execute the command, and return some kind of result. I don't really care about the result yet, but we'll name it CommandResult, and build out that class as we go. I also really like the following way of calling the executor (like in the Domain Events post), so I'll implement an NServiceBus.Publish way of executing the command as well:
CommandResult result = executor.Execute<SomeCommand>(msg => { });
Let's create the SomeCommand too, and make it inherit an abstract empty Command class. This way we can easily put some constraints on our CommandExecutor later on:
public class SomeCommand: Command {}
public abstract class Command { }
Okay, so we have two methods on our interface, and it should look like this:
public interface ICommandExecutor { CommandResult Execute(Command command); CommandResult Execute<T>(Action<T> commandConstructor) where T: Command, new(); }
As you see, we can constrain the T in the second method to a Command implementation. You'll see why we need the new() constraint later on.
Implementing the CommandExecutor
So we have the interface for our Executor, so let's try to implement it.
public class CommandExecutor: ICommandExecutor { public CommandResult Execute(Command command) { throw new NotImplementedException(); }public CommandResult Execute<T>(Action<T> commandConstructor) where T: Command, new() { throw new NotImplementedException(); }
}
The Execute<T> method can simply build the Command and pass it on to the first method, so that implementation can simply be something like this:
public CommandResult Execute<T>(Action<T> commandConstructor) where T: Command, new() { T command = new T(); commandConstructor(command); return Execute(command); }
And here you see the reason for the new() constraint. I need to be able to construct an instance of the T in order to pass it to the commandConstructor.
Now for the actual Execute(Command command) method:
public CommandResult Execute(Command command) { dynamic handler = FindHandlerForCommand(command);try { } catch(Exception exception) { } }
Let's stop there for now. I need a way to find the Handler for my command. I didn't talk about handlers until now, so let's sidestep to that a bit.
What I want to do is have a simple Command class that has nothing but properties on it. The properties will be only the information that is needed to carry out the operation. Let's imagine a web page where we can register as a new user. We could then implement a RegisterANewUser (whether or not you want to append 'Command' after your commands is really your choice. I prefer not to, as they're usually put in a Commands-namespace anyway)
public class RegisterANewUser: Command { public string Username { get; set; } public string Password { get; set; } public string Email {get; set; } }
As you see, the command contains properties for only the information that is absolutely required for the operation that registers a new user in the system. Form validation and such should be done on the ViewModel and in the controller before executing the command, as usual.
Now we need a handler for this command, so let us define an interface first:
public interface IHandleCommand<T> where T: Command { void Handle(T command); }
That should be all we need, and the actual handler for our command would be something like this:
public class RegisterANewUserCommandHandler: IHandleCommand<RegisterANewUser> { public void Handle(RegisterANewUser command) { // this is where we do our operation } }
Given this new interface we now know what we need to do in our executor. We need to resolve whatever class implements the interface IHandleCommand for the Command passed in. Let's go ahead and implement the FindHandlerForCommand using pretty basic reflection stuff:
private object FindHandlerForCommand(Command command) { var handlerType = typeof(IHandleCommand<>).MakeGenericType(command.GetType());}
But, wait! I'm getting ahead of myself again! How should we resolve an instance of the handler? I suggest dependency injection. If you're unfamiliar with this concept, you should read about it, but basically it allows us to register in some sort of IOC Container what classes represents different interfaces, making it easy to inject dependencies into classes (since the framework will attempt to resolve arguments needed by constructors and so on).
In this case I will actually just use the same interface as in my Domain Events post, and pull it in as a constructor argument on the CommandExecutor class:
private readonly IDependencyResolver _resolver;public CommandExecutor(IDependencyResolver resolver) { _resolver = resolver; }
Finishing up the method will now be easy:
private object FindHandlerForCommand(Command command) { var handlerType = typeof(IHandleCommand<>).MakeGenericType(command.GetType()); dynamic handler = _resolver.GetService(handlerType); return handler; }
Going back to the Execute method we can now fire off our CommandHandler passing in the command as an argument:
public CommandResult Execute(Command command) { dynamic handler = FindHandlerForCommand(command);try { handler.Handle(command); return CommandResult.Executed(); } catch(Exception exception) { return CommandResult.Failed(exception.Message); } }
The CommandResult class is implemented pretty simply as follows:
public class CommandResult { public CommandStatus Status { get; private set; } public string Message { get; private set; }public static CommandResult Executed() { return new CommandResult() { Status = CommandStatus.Executed }; } public static CommandResult Failed(string message) { return new CommandResult() { Status = CommandStatus.Failed, Message = message }; }
}
With an enum, CommandStatus:
public enum CommandStatus { Executed, Failed }
And that's it!
How do we use this thing?
Now that we've implemented interfaces and everything, using this actually makes it really easy to use, especially if you're using dependency injection. Let's picture an MVC-controller:
public class UserController: Controller { private ICommandExecutor _commandExecutor;public UserController(ICommandExecutor commandExecutor) { _commandExecutor = commandExecutor; } [HttpGet] public ActionResult Register() { return View(); } [HttpPost] public ActionResult Register(RegisterANewUserViewModel viewModel) { // let's wait a minute }
}
In the example above I'm injecting the ICommandExecutor into the constructor, and I have a simple Register action that returns a view, and one that accepts a form post. All I need to do now in the post method (in addition to ViewModel validation, which I'll leave out for the purposes of this post) is:
[HttpPost] public ActionResult Register(RegisterANewUserViewModel viewModel) { // perform viewmodel validation first!var result = _commandExecutor.Execute<RegisterANewUser>(cmd => { cmd.Username = viewModel.Username; cmd.Password = viewModel.Password; cmd.Email = viewModel.Email; }); // continue flow based on the result. }
As you can see, the controller action gets trimmed down to an absolute minimum of operations, and really cleans up the controllers. Continuing to our command handler, we can reap the fruits of dependency injection.
Since we're resolving the handler using our IDependencyResolver, we can inject dependencies into the handler as we please:
public class RegisterANewUserCommandHandler: IHandleCommand<RegisterANewUser> { private IUserRepository _userRepository;public RegisterANewUserCommandHandler(IUserRepository userRepository) { _userRepository = userRepository; } public void Handle(RegisterANewUser command) { var user = User.Create(command.Username, command.Password, command.Email); // do some validation like email exists, username exists, etc. _userRepository.Add(user); }
}
I've left out validation here as well as this is not a working example without the repository-class. How you implement the actual creation of the User is not really important here, but what is worth noting is that you can throw domain-specific exceptions in your handler, and the execution will result in a CommandResult.Failed with the exception message returned. This also removes the need for try-catch blocks within your actions (or wherever you execute your commands from).
So why should we do this?
Whether or not you choose to go all out CQRS or not, the command part of it can really do wonders to your codebase. In the above example, we see that our controllers are clean from CRUD-operations and excess constructor injections. Another important up-side is that you will get an arsenal of commands and handlers that documents your domain. We already have a handler that describes the registration of a new user. By looking in my commands folder, I quickly see that command, and I know exactly where the logic for the operation is.
My post on Domain Events is a nice supplement to this (You can also use the IoC registration for DomainEvents from that post and do the same for your CommandHandlers). As an example we could do something like this in the RegisterANewUserCommandHandler:
public void Handle(RegisterANewUser command) { var user = User.Create(command.Username, command.Password, command.Email); // do some validation like email exists, username exists, etc. _userRepository.Add(user); DomainEvents.Raise(ANewUserWasRegistered() { User = user }); }
This domainevent could then be used to update a readmodel (CQRS), or execute further user-specific tasks, like sending a welcome mail to the user, etc.
Hope you found this post useful, and stay tuned for more!