Commands, Command Handlers and Command Dispatcher

In this post, I am trying to add some CQRS principles onto my EFMVC project. EFMVC is a small web app for demonstrating ASP.NET MVC and EF Code First. Please keep in mind that this is not the implementation CQRS patterns, but trying to add some CQRS flavors on the Solution Architecture with Commands that changes the data (Create, Update and Delete). The current implementation of command execution is implemented in a synchronous way. 

CQRS 

CQRS is stands for Command-Query Responsibility Segregation that is a principle of separating commands (that change the data) from queries (that read the data). The CQRS pattern is first described by Greg Young and his blog post CQRS, Task Based UIs, Event Sourcing agh! has explained about this approach. If you want to build real world CRQS based apps, I highly recommending to read Rinat Abdullin's blog and the CQRS info site.

Domain Entity

The below domain entity Category is using for demo  application

public class Category
{
    public int CategoryId { getset; }
    [Required]
    public string Name { getset; }
    public string Description { getset; }
}

 
Command


Every write operations represent a command and these commands will be executed by using a Command Handler.  Let’s add command object CreateOrUpdateCategoryCommand for representing the Create and Update write operation. The CreateOrUpdateCategoryCommandis is representing the write operation for the domain entity Category. 

public class CreateOrUpdateCategoryCommand : ICommand
{
    public CreateOrUpdateCategoryCommand(int CategoryId,string name, string description)
    {
        this.CategoryId = CategoryId;
        this.Name = name;
        this.Description = description;
    }
    public int CategoryId { getset; }
    public string Name { getset; }
    public string Description { getset; }
}


The interface ICommand is now just using for IoC purpose to hook corresponding Command Handler object.

public interface ICommand  { }

Command Handler


 The following code is shown the Command Handler for the command object CreateOrUpdateCategoryCommand.

public class CreateOrUpdateCategoryHandler 
                : ICommandHandler<CreateOrUpdateCategoryCommand>
{
    private readonly ICategoryRepository categoryRepository;
    private readonly IUnitOfWork unitOfWork;
    public CreateOrUpdateCategoryHandler(ICategoryRepository categoryRepository,
        IUnitOfWork unitOfWork)
    {
        this.categoryRepository = categoryRepository;
        this.unitOfWork = unitOfWork;
    }
    public ICommandResult Execute(CreateOrUpdateCategoryCommand command)
    {
        var category = new Category
        {
            CategoryId = command.CategoryId,
            Name = command.Name,
            Description = command.Description
        };
        if (category.CategoryId == 0)
            categoryRepository.Add(category);
        else
            categoryRepository.Update(category);
        unitOfWork.Commit();
        return new CommandResult(true);
    }
}

 The CreateOrUpdateCategoryHandler object will perform the data persistence for the command operation CreateOrUpdateCategoryCommand.

The ICommandHandler<T> interface is shown below

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

 Command Validator


Every command object would be submitted to a Command Bus that will be hook the right command handler and will execute the command operation. In this demo app, we just validate the command before submitting the command to command bus.


The following class is using for validating the business rules for our command CreateOrUpdateCategoryCommand

public class CanAddCategory : IValidationHandler<CreateOrUpdateCategoryCommand>
{
    private readonly ICategoryRepository categoryRepository;      
    public CanAddCategory(ICategoryRepository categoryRepository, 
        IUnitOfWork unitOfWork)
    {
        this.categoryRepository = categoryRepository;           
    }
    public IEnumerable<ValidationResult> Validate(
        CreateOrUpdateCategoryCommand command)
    {
        Category isCategoryExists=null;
        if(command.CategoryId==0)
            isCategoryExists = categoryRepository.Get(c => c.Name == command.Name);
        else
            isCategoryExists = categoryRepository.Get(c => c.Name == command.Name 
                && c.CategoryId!=command.CategoryId);
        if (isCategoryExists!=null )
        {
            yield return new ValidationResult("Name"Resources.CategoryExists);
        }
    }
}

 
The IValidationHandler<T> interface is shown below

public interface IValidationHandler<in TCommand> where TCommand : ICommand
{
    IEnumerable<ValidationResult>  Validate(TCommand command);
}


Command Dispatcher


The responsibility of the Command Dispatcher object is to hook right Command Handler object based on the command object we have submitted to the Command Dispatcher object. Autofac IoC container is using to hook the Command Handler object for the given command object.


The following is the contract type of Command Dispatcher

public interface ICommandBus
{
ICommandResult Submit<TCommand>(TCommand command) where TCommand: ICommand;
IEnumerable<ValidationResult> Validate<TCommand>(TCommand command) 
                                        where TCommand : ICommand;
}

 
The default implementation of the ICommandBus is shown below


public class DefaultCommandBus : ICommandBus
{
public ICommandResult Submit<TCommand>(TCommand command) where TCommand: ICommand
{    
  var handler = DependencyResolver.Current.GetService<ICommandHandler<TCommand>>();
    if (!((handler != null) && handler is ICommandHandler<TCommand>))
    {
        throw new CommandHandlerNotFoundException(typeof(TCommand));
    }  
    return handler.Execute(command);
 
}
public IEnumerable<ValidationResult> Validate<TCommand>(TCommand command) where TCommand : ICommand
{
  var handler = DependencyResolver.Current.GetService<IValidationHandler<TCommand>>();
    if (!((handler != null) && handler is IValidationHandler<TCommand>))
    {
        throw new ValidationHandlerNotFoundException(typeof(TCommand));
    }  
    return handler.Validate(command);
}
}

The command bus provides two methods – Submit and Validate. The submit method will execute the appropriate command handler object and the validate method is used for validating the command object before submitting the command. The default command bus object provides the command execution in a synchronous way. In many real world CQRS implementations, this would be in an asynchronous way.

Component Registration in Autofac

The following code is using in the EFMVC project to register components with Autofac.

private static void SetAutofacContainer()
{
    var builder = new ContainerBuilder();          
    builder.RegisterControllers(Assembly.GetExecutingAssembly());
    builder.RegisterType<DefaultCommandBus>().As<ICommandBus>()
        .InstancePerHttpRequest();
    builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerHttpRequest();
    builder.RegisterType<DatabaseFactory>().As<IDatabaseFactory>()
        .InstancePerHttpRequest();
    builder.RegisterAssemblyTypes(typeof(CategoryRepository).Assembly)
    .Where(t => t.Name.EndsWith("Repository"))
    .AsImplementedInterfaces().InstancePerHttpRequest();          
    var services = Assembly.Load("EFMVC.Domain");
    builder.RegisterAssemblyTypes(services)
    .AsClosedTypesOf(typeof(ICommandHandler<>)).InstancePerHttpRequest();
    builder.RegisterAssemblyTypes(services)
    .AsClosedTypesOf(typeof(IValidationHandler<>)).InstancePerHttpRequest();
    builder.RegisterType<DefaultFormsAuthentication>().As<IFormsAuthentication>()
        .InstancePerHttpRequest();
    builder.RegisterFilterProvider();
    IContainer container = builder.Build();                  
    DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}      

ASP.NET MVC Controller 

In our demo app, the command object CreateOrUpdateCategoryCommand is creating and submitting to Command Bus from a ASP.NET MVC controller action method. In the following action method, we are creating the CreateOrUpdateCategoryCommand object form values and calling the Validate method of command bus. If the command is valid, we will submit the command object to the Command Bus that will execute the command operation in a synchronous way.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Save(CategoryFormModel form)
{
if(ModelState.IsValid)
{
    var command = new CreateOrUpdateCategoryCommand(form.CategoryId,form.Name,
        form.Description);
    IEnumerable<ValidationResult> errors=  commandBus.Validate(command);
    ModelState.AddModelErrors(errors);    
    if (ModelState.IsValid)
    {
        var result = commandBus.Submit(command);
        if (result.Success) return RedirectToAction("Index");                 
    }                
}   
//if fail
if (form.CategoryId == 0)
    return View("Create",form);
else
    return View("Edit", form);
}         

Source Code

The source code of EFMVC available from http://efmvc.codeplex.com/.  



Published Tuesday, October 18, 2011 10:57 PM by shiju

Comments

# re: CQRS, Commands, Command Handlers and Command Dispatcher

Wednesday, October 19, 2011 4:51 AM by Mauro Servienti

Just a couple of notes:

- the title is misleading, as you say in the first lines this has nothing to share with CQRS, but only with the "C" portion;

- the CreateOrUpdateCategoryCommand from a DDD point of view has no sense, a command cannot have more than one possible behavior, the invoker must know if the Category should be created or updated;

- from a DDD point of view Update is not a valid concept, it does not highlight the intent, ChangeCategoryDescription has much more sense;

.m

# re: CQRS, Commands, Command Handlers and Command Dispatcher

Wednesday, October 19, 2011 10:35 AM by Paul Irwin

Some good stuff going on here. The last code snippet of the controller code bothers me. Yes, using "yield return" is cool and all, but you have it enumerating your validator twice -- once using Count(), the other when ModelState.AddModelErrors will enumerate it. Since both enumerations will perform an operation on your repository, that is likely a performance hit that is unnecessary. At the very least, the code should be calling .Any() instead of .Count() so that it only does one enumeration step instead of n. But even better, I would either change the signature of the Validate call to return ICollection<ValidationResult> instead of IEnumerable<ValidationResult> so that the enumeration only happens once, or call .ToList() after calling .Validate(command) to force one enumeration. After having a collection instead of an enumerable, you can use the non-enumerating .Count property and have prevented an inefficiency. I love IEnumerable<T> with "yield return" as much as the next guy, but often other programmers end up abusing it and enumerating multiple times unnecessarily.

# re: CQRS, Commands, Command Handlers and Command Dispatcher

Wednesday, October 19, 2011 12:15 PM by Satish

I think we can do a much better command implementation.. It doesnt need to use Service locator pattern...

# re: Commands, Command Handlers and Command Dispatcher

Thursday, October 20, 2011 10:34 AM by shiju

Hi All, The primary objective of the EFMVC application is to demonstrate ASP.NET MVC and EF Code First. As I said earlier, this not the implementation CQRS patterns, but trying to add few flavors in synchronous execution way.

# re: Commands, Command Handlers and Command Dispatcher

Sunday, June 9, 2013 4:10 AM by Goff

Good way of describing, and good post to obtain

information on the topic of my presentation focus, which i am

going to convey in university.

# re: Commands, Command Handlers and Command Dispatcher

Friday, December 6, 2013 12:32 AM by Mojammel

Hi

Nice post. I really enjoyed it.

Can you please implement event sourcing (ES) with this architecture?

Thanks in advance.

# re: Commands, Command Handlers and Command Dispatcher

Sunday, December 8, 2013 4:25 PM by Salley

Thanks for finally talking about >Commands, Command Handlers and Command Dispatcher - Shiju Varghese's

Blog <Liked it!

Leave a Comment

(required) 
(required) 
(optional)
(required)