Command and Query Handlers

In my previous post, I talked about some Command and Query handlers. The implementation I made is in .NET using C#. Here is what a command handler looks like:

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

public class DeleteUserCommand : ICommand
{
    public Guid Id { get; set; }
}

public class DeleteUserCommandHandler : ICommandHandler<DeleteUserCommand>
{
    private readonly ISession _session;

    public DeleteUserCommandHandler(ISession session)
    {
        _session = session;
    }

    public void Handle(DeleteUserCommand command)
    {
        //handle command  
    }
}

There is also a command dispatcher that will dispatch the necessary handlers to execute the commands. This one does it synchronously, but it can be turned async quite easily.

public class DefaultCommandBus : ICommandBus
{
   ...
   public void SubmitCommand<TCommand>(TCommand command) where TCommand : ICommand
   {
      var handler = _commandHandlerFactory.GetHandler<TCommand>();
      try
      {
          handler.Handle(command);
      }
      finally
      {
          _commandHandlerFactory.ReleaseHandler(handler);
      }
   }
}

CommandHandlerFactory simply resolves the required handler using a DI container and is also reponsible for releasing the handler.

On the query side, there is a QueryService that executes the query and returns the result. This makes some use of the dynamic keyword trickery to provide a strongly typed API.

public interface IQuery<TResult> : IQueryBase {}

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

public class QueryService
{
  public TResult ExecuteQuery<TResult>(IQuery<TResult> query)
  {
     var handlerType = typeof (IQueryHandler<,>).MakeGenericType(query.GetType(), typeof (TResult));
     var handler = _container.Resolve(handlerType);
     try
     {
        return (TResult)((dynamic)handler).Execute( (dynamic)query);
     }
     finally
     { 
        _container.Release(handler);
     }
  }
}

You can simply use the query as follows, and it will return a strongly typed result.

var query = new SearchUsersQuery { SearchTerm = "term" };
var result = _queryService.ExecuteQuery(query);
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s