Print

Meanwhile... on the command side of my architecture

This article describes how a single interface can transform the design of your application to be much cleaner, and more flexible than you ever thought possible.

If you find this article interesting, you should also read my follow up: Meanwhile... on the query side of my architecture.

Since I began writing applications in .NET I've been separating operations that mutate state (of the database mostly) from operations that return data. This is basically what the Command-query separation principle is about. Over time the designs I have used have evolved. Initially triggered by a former colleague of mine I started to use the Command Pattern about four years ago. Back then we called them business commands and a single command would represent an atomic business operation, or use case.

Over the years, the projects I have participated on have increased in complexity and I have adopted newer techniques such as Test Driven Development and Dependency Injection (DI). The flaws in this approach to the Command Pattern have become obvious to me. DI has a tendency of exposing violations of the SOLID principles and this implementation hindered the maintainability of these applications.

In the early days my implementation of the Command Pattern design consisted of classes that contained both properties to hold the data and an Execute() method that would start the operation. The design had an abstract Command base class that contained all of logic for handling transactions, re-executing commands after a deadlock occurred, measuring performance, security checks, etc. This base class was a big code smell and was a form of God Object with many responsibilities. Furthermore, having data and behavior interleaved made it very difficult to mock/abstract that logic during unit testing. For example a consumer of a command would typically new up a command instance and call Execute() directly on it, as shown in the following example:

var command = new MoveCustomerCommand
{
CustomerId = customerId,
NewAddress = address
};

command.Execute();

I tried to solve this problem by injecting the command into the constructor of a consumer (constructor injection), but this was awkward to say the least. It remained the responsibility of the consumer to set all the properties of the object that was passed in and didn't really solve the problem of abstracting away the command elegantly. To prevent the command's logic from being executed, I had to define a fake version of each command for testing and it did nothing to reduce the large and complicated base class.

All of these experiences led me to try a design that I had seen others use, but that I had never seen the benefits of. In this new design, data and behavior are separated. Each business operation has a simple data container called the command object (a DTO); my standard naming convention for these classes is to suffix them with 'Command':

public class MoveCustomerCommand
{
public int CustomerId { get; set; }

public Address NewAddress { get; set; }
}

The logic gets its own separate class; my standard naming convention for these classes is to suffix them with 'CommandHandler':

public class MoveCustomerCommandHandler
{
private readonly UnitOfWork db;

public MoveCustomerCommandHandler(UnitOfWork db, [Other dependencies here])
{
this.db = db;
}

public virtual void Handle(MoveCustomerCommand command)
{
// TODO: Logic here
}
}

This design gives us a lot; a command handler can be injected into a consumer, while the consumer can simply new up the related command object. Because the command only contains data, there no longer a reason to fake the command during testing. Here’s an example of how a consumer can use that command and command handler:

public class CustomerController : Controller
{
private readonly MoveCustomerCommandHandler handler;

public CustomerController(MoveCustomerCommandHandler handler)
{
this.handler = handler;
}

public void MoveCustomer(int customerId, Address newAddress)
{
var command = new MoveCustomerCommand
{
CustomerId = customerId,
NewAddress = newAddress
};

this.handler.Handle(command);
}
}

There is still a problem with this design. Although every handler class has a single (public) method (and therefore adheres the Interface Segregation Principle), all handlers define their own interface (there is no common interface). This makes it hard to extend the command handlers with new features and cross-cutting concerns. For example, we would like to measure the time it takes to execute every command and log this information to the database. How can we do this? In the past we would either change each and every command handler, or move the logic into a base class. Moving this feature into the base class is not ideal as the base class will soon contain lots of these common features, and would soon grow out of control (which I have seen happening). Besides, this would make it hard to enable/disable such behavior for certain types (or instances) of command handlers because it would involve adding conditional logic into the base class, making it even more complicated!

All these problems can be solved elegantly by having all command handlers implement a single generic interface:

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

Using this interface, the MoveCustomerCommandHandler would now look like this:

// Exactly the same as before, but now with the interface.
public class MoveCustomerCommandHandler : ICommandHandler<MoveCustomerCommand>
{
private readonly UnitOfWork db;

public MoveCustomerCommandHandler(UnitOfWork db, [Other dependencies here])
{
this.db = db;
}

public void Handle(MoveCustomerCommand command)
{
// TODO: Logic here
}
}

One important benefit of this interface is that it allows the consumers to depend on the new abstraction, rather than a concrete implementation of the command handler:

// Again, same implementation as before, but now we depend
// upon the ICommandHandler abstraction.
public class CustomerController : Controller
{
private ICommandHandler<MoveCustomerCommand> handler;

public CustomerController(ICommandHandler<MoveCustomerCommand> handler)
{
this.handler = handler;
}

public void MoveCustomer(int customerId, Address newAddress)
{
var command = new MoveCustomerCommand
{
CustomerId = customerId,
NewAddress = newAddress
};

this.handler.Handle(command);
}
}

What does adding an interface give us? Well frankly, a lot! Since nothing depends directly on any implementation but instead depends on an interface, we can now replace the original command handlers with any class that implements the new interface. Ignoring, for now the usual argument of testability, look at this generic class:

public class TransactionCommandHandlerDecorator<TCommand> : ICommandHandler<TCommand>
{
private readonly ICommandHandler<TCommand> decorated;

public TransactionCommandHandlerDecorator(ICommandHandler<TCommand> decorated)
{
this.decorated = decorated;
}

public void Handle(TCommand command)
{
using (var scope = new TransactionScope())
{
this.decorated.Handle(command);

scope.Complete();
}
}
}

This class wraps an ICommandHandler<TCommand> instance (by accepting an instance of the same interface in its constructor), but at the same time it also implements the same ICommandHandler<TCommand> interface. It is an implementation of the Decorator pattern. This very simple class allows us to add transaction support to all of the command handlers.

Instead of injecting a MoveCustomerCommandHandler directly into the CustomerController, we can now inject the following:

var handler =
new TransactionCommandHandlerDecorator<MoveCustomerCommand>(
new MoveCustomerCommandHandler(
new EntityFrameworkUnitOfWork(connectionString),
// Inject other dependencies for the handler here
)
);

// Inject the handler into the controller’s constructor.
var controller = new CustomerController(handler);

This single decorator class (containing just 5 lines of code) can be reused for all of the command handlers in the system.

In case you're still not convinced, let's define another decorator:

public class DeadlockRetryCommandHandlerDecorator<TCommand> : ICommandHandler<TCommand>
{
private readonly ICommandHandler<TCommand> decorated;

public DeadlockRetryCommandHandlerDecorator(ICommandHandler<TCommand> decorated)
{
this.decorated = decorated;
}

public void Handle(TCommand command)
{
this.HandleWithCountDown(command, 5);
}

private void HandleWithCountDown(TCommand command, int count)
{
try
{
this.decorated.Handle(command);
}
catch (Exception ex)
{
if (count <= 0 || !IsDeadlockException(ex))
throw;

Thread.Sleep(300);

this.HandleWithCountDown(command, count - 1);
}
}

private static bool IsDeadlockException(Exception ex)
{
while (ex != null)
{
if (ex is DbException && ex.Message.Contains("deadlock"))
return true;

ex = ex.InnerException;
}

return false;
}
}

This class should speak for itself - although it contains more code than the previous example, it is still only 14 lines of code. In the event of a database deadlock, it will retry the command 5 times before it leaves the exception bubble up through the call stack. As before we can use this class by wrapping the previous decorator, as follows:

var handler =
new DeadlockRetryCommandHandlerDecorator<MoveCustomerCommand>(
new TransactionCommandHandlerDecorator<MoveCustomerCommand>(
new MoveCustomerCommandHandler(
new EntityFrameworkUnitOfWork(connectionString),
// Inject other dependencies for the handler here
)
)
);

var controller = new CustomerController(handler);

By the way, did you notice how both decorators are completely focused? They each have just a single responsibility. This makes them easy to understand, easy to change - this is what the Single Responsibility Principle is about.

The downside of these changes is that it can require a lot of boilerplate code to wire up all the classes that depend on a command handler; but at least the rest of the application is oblivious to this change. When dealing with any more than a handful of command handlers you should consider using a Dependency Injection framework. Such a framework can automate this wiring for you and will assist in making this area of your application maintainable.

The system depends on the correct wiring of these dependencies, since wrapping the deadlock retry behavior with the transaction behavior would lead to unexpected behavior (since a database deadlock typically has the effect of the database rolling back the transaction, while leaving the connection open), but this is isolated to the part of the application that wires everything together. Again, the rest of the application is oblivious.

Both the transaction logic and deadlock retry logic are examples of cross-cutting concerns. The use of decorators to add cross-cutting concerns is the cleanest and most effective way to apply these common features. It is a form of Aspect Oriented Programming. Besides these two examples there are many other cross-cutting concerns I can think of that can be added fairly easy using decorators:

  • checking the authorization of the current user before commands get executed,
  • validating commands before commands get executed, 
  • measuring the duration of executing commands, 
  • logging and audit trailing,
  • executing commands in the background, or
  • queuing commands to be processed in a different process.

<BackgroundStory>This last one is a very interesting one. Years ago I worked on an application that used a database table as queue for commands that would be executed in the future. We wrote business processes (commands by themselves) that sometimes queued dozens of other (sub) commands, which could be processed in parallel by different processes (multiple Windows services on different machines). These commands did things like sending mail or heavy stuff such as payroll calculations, generating PDF documents (that would be merged by another command, and sending those merged documents to a printer by yet another command). The queue was transactional, which allowed us to -in a sense- send mails and upload files to FTP in a transactional manner. However, We didn't use dependency injection back then, which made everything so much harder (if only we knew).</BackgroundStory>

Because commands are simple data containers without behavior, it is very easy to serialize them (using the XmlSerializer for instance) or send them over the wire (using WCF for instance), which makes it not only easy to queue them for later processing, but ot also makes it very easy to log them in an audit trail- yet another reason to separate data and behavior. All these features can be added, without changing a single line of code in the application (except perhaps a line at the start-up of the application).

This design makes maintaining web services much easier too. Your (WCF) web service can consist of only one 'handle' method that takes in any command (that you explicitly expose) and can execute these commands (after doing the usual authentication, authorization, and validation of course). Since you will be defining commands and their handlers anyway, your web service project won't have to be changed. If you're interested, take a look at my article Writing Highly Maintainable WCF Services.

One simple ICommandHandler<TCommand> interface has made all this possible. While it may seem complex at first, once you get the hang of it (together with dependency injection), well... the possibilities are endless. You may think that you don’t need all of this up front when you first design your applications but this design allows you to make many unforeseen changes to the system later without much difficulty. One can hardly argue a system with this design is over-engineered, since every business operation has its own class and we have put a single generic interface over them all. It’s hard to over-engineer that - even really small systems can benefit from separating concerns.

This doesn't mean things can’t get complicated. Correct wiring all of these dependencies, and writing and adding the decorators in the right order can be challenging. But at least this complexity is focused in a single part of the application (the start-up path a.k.a. Composition Root), and it leaves the rest of the application unaware and unaffected. You will rarely need to make sweeping changes across your application, which is what the Open/Closed Principle is all about.

By the way, you probably think the way I created all those decorators around a single command handler is rather awkward, and imagined the big ball of mud that it would become after we have created a few dozen command handlers. Yes, you are right - this doesn’t scale well. But as I already mentioned, this problem is best resolved with a DI framework. For instance, when using Simple Injector, registering all command handlers in the system can be done with a single line of code. Registering a decorator is another single line. Here is an example configuration when when using Simple Injector:

using SimpleInjector;
using SimpleInjector.Extensions;

var container = new Container();

// Go look in all assemblies and register all implementations
// of ICommandHandler<T> by their closed interface:
container.RegisterManyForOpenGeneric(typeof(ICommandHandler<>),
AppDomain.CurrentDomain.GetAssemblies());

// Decorate each returned ICommandHandler<T> object with
// a TransactionCommandHandlerDecorator<T>.
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(TransactionCommandHandlerDecorator<>));

// Decorate each returned ICommandHandler<T> object with
// a DeadlockRetryCommandHandlerDecorator<T>.
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(DeadlockRetryCommandHandlerDecorator<>));

// Decorate handlers conditionally with validation. In
// this case based on their metadata.
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(ValidationCommandHandlerDecorator<>),
c => ContainsValidationAttributes(c.ServiceType));

// Decorates all handlers with an authorization decorator.
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(AuthorizationCommandHandlerDecorator<>));

No matter how many command handlers you add to the system, these few lines of code won’t change, which also helps to underline the true power of a DI framework. Once your application is built applying the SOLID principles, a good DI framework will ensure that the startup path of your application remains maintainable.

This is how I roll on the command side of my architecture.

If you found this article interesting, you should also read my follow up: Meanwhile... on the query side of my architecture and take a look how to return data from command handlers. In Writing highly maintainable WCF services I talk about sending commands over the wire.

- .NET General, Architecture, C#, Dependency injection - 30 comments / No trackbacks - §

The code samples on my weblog are colorized using javascript, but you disabled javascript (for my website) on your browser. If you're interested in viewing the posted code snippets in color, please enable javascript.

30 comments:

SOLID article! thanks! :)
Evaldas Dauksevičius - 23 12 11 - 12:24

I had been playing with a few similar concepts, reading your article really helped me get to grip on what it was I was trying to achieve, a great help thanks!
Ian - 27 08 12 - 12:15

Great article !
turbot - 09 11 12 - 15:16

Nice article, thanks! Interesting ideas and well explained.

I have a question of how you handle cases (or how you manage not to have them) when a consumer is interested in a result of the command handling? For example, when command is - entity creation and consumer is interested in entity id which is generated during command handling.
Alexey Zuev - 11 11 12 - 14:25

Hi Alexey,

Returning data from command handlers is something I explain in one of my later articles: http://www.cuttingedge.it/blogs/steven/p..
Steven (URL) - 11 11 12 - 15:09

The AutoFac registration part equivalent is:

var assemblies = AppDomain.CurrentDomain.GetAssemblies();

builder.RegisterAssemblyTypes(assemblies)
    .As(t => t.GetInterfaces()
    .Where(a => a.IsClosedTypeOf(typeof(ICommandHandler<>)))
    .Select(a => new KeyedService("commandHandler", a)));

builder.RegisterGenericDecorator(
    typeof(TransactionCommandHandlerDecorator<>),
    typeof(ICommandHandler<>),
    fromKey: "commandHandler");
Graeme - 23 11 12 - 17:10

Great series of articles.

Should there only ever be one command handler for a command? My assumption is yes and that the handler can raise domain events for further participation. This makes sense if you consider a command & handler as corresponding to use cases.
Rick - 28 11 12 - 21:55

@Rick, if you have more than one command handler per command, there might be something wrong with your design. A command handler is the implementation of a use case and it should be atomic, so it makes little sense to split this up in multiple handlers. For event handlers on the other hand, it would be very likely to have multiple.
Steven - 29 11 12 - 06:15

Hi Steven.
In the examples above you execute the command handlers inside the controller.

Do you consider the command handlers to be part of your domain? I wondered the same for your post on the query side too.

My initial thoughts are that both commands and queries encapsulate domain requirements, so therefore represent part of the domain layer itself. However I have seen examples (most notably on Martin fowlers bliki) that suggest commands are executed by the domain as they are atomic operations executed as a result of decisions made within the domain layer.

Great articles, have enjoyed reading them and have found a lot of the code very useful
Guy - 17 02 13 - 20:35

Guy,

This post only talks about the SOLID aspects of this design. Your question deserves a whole blog post on its own, but I definitely see commands as part of the domain. They should be named in a way that makes sense to the business and a command should be atomic. If you want to run multiple commands in one transaction, you are probably dealing with a single command.

Keep an eye on my blog. I will certainly write more about this subject in the future.
Steven (URL) - 17 02 13 - 21:56

Hi Steven,

great article thank you for sharing it.

I wonder if MoveCustomerCommand could be interface instead? Do you see any problems with it?

Best regards
Dzenan - 24 02 13 - 13:19

Hi Dzenan,

Let me turn it the other way around: what would be the use of adding an interface to a DTO? Since a DTO only contains data, and no logic, their should be no reason ever to abstract that type, since you would typically only abstract behavior, not data.

So the problem is that you will create a useless abstraction that will only be in the way when writing your application, writing your tests and wiring your application in the DI container.

This doesn't mean however, that your commands can't implement any interfaces. On the contrary, interfaces can help you in applying cross-cutting concerns conditionally, in a very natural way. Take a look at this command and decorator:

public class ShipOrderCommand : IAsyncCommand { }

public class AsyncCommandHandlerDecorator<T>
    : ICommandHandler<T>
    where T : IAsyncCommand
{
    // logic
}

// The decorator will automatically be applied to command
// handlers that satisfy the generic type constraint.
container.RegisterDecorator(
    typeof(ICommandHandler<>),
    typeof(AsyncCommandHandlerDecorator<>));
Steven (URL) - 24 02 13 - 13:46

Hello great article.
Would it be bad practice to call commands from within a command? Or should you call each single command from the controller?
mike - 01 06 13 - 16:22

@Mike, although this isn't bad practice per see, I think it's best to define a command as an atomic operation and use ICommandHandler(Of T) only as abstraction between the presentation layer and the business layer (not within the BL). This makes it much easier to apply cross-cutting concerns to command handlers, since most cross-cutting concerns should not be applied to the inner command handlers (i.e. you don't want to start a new transaction for an inner command).
Steven (URL) - 01 06 13 - 17:36

Hello Steven,
Excellent article. I got a lot from it. Thanks. Was just wondering if you implemented this behind an MVC site which used ViewModels to display data, would you recommend still having the command DTO's to pass to the command handlers? Then I will have 2 levels of mapping to do - View Model to Command, then Command to Domain Entity. Which will give me a nicer abstraction if a different client was to use the commands. But in my scenario it leads to some DTO repetition. What are your thoughts on this? Thanks for your time.
sean - 07 06 13 - 17:43

Hi Sean,

MVC has great model binding and compile time capabilities, so in general I would not recommend creating view models that are duplicates of your commands. Instead use the command as property in your view model. Example:


public class MoveCustomerViewModel
{
    public MoveCustomerCommand Command { get; set; }

    // Extra properties needed to render the view
    public IEnumerable Customers { get; set; }
}
Steven (URL) - 07 06 13 - 18:22

Steven - Great article & info, thanks!

One question I have is what if a controller might want to call 10 different commands...doesn't that get a bit burdensome with constructor injection? The registration part is easy with SimpleInjector for example, but it seems unwieldy to inject so many dependencies via constructor.
Paul - 03 07 13 - 17:32

@Paul: I take the liberty to answer that.
If your class needs ten different commands it most likely violates the Single Responsibility Principle.

There are two different ways you can fix it. Which one is appropriate depends on your actual class.

Scenario 1:
Your class has several public methods, each of which uses only a subset of the provided commands.
Solution: Break your class apart into smaller classes, each with a focused responsibility

Scenario 2:
All ten commands are used by one method.
This means that there probably is an abstraction that you didn't yet extract.
Solution: Extract an abstraction that encapsulates a part of your method and exposes a higher level interface and internally uses some of the commands.
Further reading for this scenario: http://blog.ploeh.dk/2010/02/02/Refactor..
Daniel Hilgarth (URL) - 03 07 13 - 17:45

@Paul,

@Daniel is spot on with his answer. But I like to extend Daniel's second scenario a bit.

A command should have (or at least in my view on it) a one-to-one correspondence with a use case. When you handle a request for a user (when MVC calls one of your Action methods) that is always one use case; never more. So you should never execute more than one command in a action method.

Although in general, the answer would be to wrap this in an Aggregate Service, as Daniel says, in this case that Aggregate Service itself would become the use case and thus the command handler.

Command handlers however, should not depend (directly or indirectly) on other command handlers. The ICommandHandler abstraction should just be a thin layer between your Presentation Layer and Business Layer. This command handler can still depend on other dependencies that might do the actual work, but not on other command handlers. This flat hierarchy is easier to follow, but more importantly, nesting command handler makes it much harder to apply cross-cutting concerns, since most cross-cutting concerns should only be applied to the handler that it triggered directly from the presentation layer. Think about applying transactions and deadlock retry for instance. See your ICommandHandler as your gateway to the business layer.
Steven (URL) - 03 07 13 - 22:00

Thanks both Daniel & Steven!

Very good info that I've had a little while to digest, and in fact am implementing some code now based upon the over-injection post that Daniel directed me to.

My question still sort of remains though - what if I have a scenario, say a Message Processing Server, where they may be many commands:

CreateNewUserCommand
UpdateUserPrefsCommand
DeleteUserCommand
SendUserNotificationCommand
... (My imagination fails me, but there could be many more)

This could be in a controller, or just a standalone server. Now, I want all of these handlers to be available to the Server/Controller, but I still may suffer from the same over-injection disease without breaking any of the other principals. No command interdependency etc. You can imagine that in a UserAccountController for example, you wouldn't be breaking the SRP but still may have a lot of Commands.

BTW - To remedy my current situation I aggregated like-commands into command processors and will inject 2 of them instead of 6 handlers.
Paul - 03 07 13 - 22:09

This would be an unusual case for a Controller to need, but not for a Windows Service or WCF service. A Windows Service would typically be used to read from a queue with commands and execute those commands. WCF will process incoming commands.

Both services will deserialize objects from XML, JSON or some other format back into .NET classes and use and use metadata to get the actual command type and resolve the corresponding command handler. You can see an example of this here: http://www.cuttingedge.it/blogs/steven/p..

But if you have multiple types of applications that need to have this same processing logic, in that case you need some kind of factory for command handlers, a ICommandProcessor. Something like:

public interface ICommandProcessor
{
    void Process(object command);
}

Your WCF service, and Windows Service can both call the ICommandProcessor and its implementation will do the reflection as shown in the linked article.
Steven - 03 07 13 - 22:28

This is perhaps one of the best posts I have read in a long time! It has really opened my eyes on the power of decorators and I'll have to be careful not to overuse the concept everywhere. Thank you for taking the time to write and share quality knowledge.
Mike - 12 07 13 - 20:18

Hi Steven, this is a very interesting article with some great ideas.

I was wondering how this relates to the command pattern. Would you consider this to be an implementation of the command pattern or is the name where the similarity ends?

In the standard implementation, the command objects have a uniform, no-arg execute method which makes it easy to pass the data around but most implementations I have seen end up becoming unwieldy when you start trying to add additional features such as undo (which usually add additional methods to the command classes, violating the SRP).

I can see your architecture making some of these thing much easier, for example:

public class RegisterUndoCommandHandlerDecorator : CommandHandler
{
    private UndoManager Manager { get; set; }
    private CommandHandler Wrapped { get; set; }
    
    public RegisterUndoCommandHandlerDecorator(UndoManager manager, CommandHandler wrapped)
    {
        this.Manager = manager;
        this.Wrapped = wrapped;
    }

    public void Handle(T command)
    {
        // The manager is responsible for actually determining the 'undoable'
        // command handler for a given command...
        this.Manager.Register(Command);
        this.Wrapped.Handle(Command);
    }
}

I would appreciate your thoughts on this.
Benjamin - 08 01 14 - 13:47

Hi Benjamin,

I don't consider this the Command Pattern, although the patterns are clearly related, since they both deal with commands. But they are also very different, since the command pattern deals with a single ICommand interface that consumers can depend on. This allows them to know nothing about the commands they execute and it allows consumers to store, execute, and undo a list of unrelated commands. Take for instance a text processor or painting application where changes are made in lots of small steps and each step must be undoable. In such application it is pretty clear you need the command pattern. For Line of Business applications however, we often deal with transactions and need to add a lot of cross-cutting concerns around those transactions. This is a clear case for the pattern as I describe in in this blog post.
Steven (URL) - 14 01 14 - 15:24

Hi Steven,

How would you arrange these classes in a larger VS project/solution?

Would you have the commands in one project and the handlers in another? Would you recommend having one single project just for interfaces?

I currently have a structure of:

- Context (EF mappings, DBContext etc)
- Model (concrete)
- Repositories (concrete)
- Services (concrete)
- Interfaces (repository and service interfaces)
- Core (contains useful helpers, extensions etc.)

Would you split services into commands and handlers and wire up everything using IoC in the client app?
Graham (URL) - 27 01 14 - 18:12

@Graham,

It all depends on context. It all depends on the size of your project, the number of developers working on it, and your application requirements.

If you are sending commands over the wire for instance (using a WCF service for instance), it becomes really useful to have some sort of 'Contract' assembly that contains just the commands. This contract assembly can be shared by the server and the client, and you could even share it with third parties. This is the approach I took in a recent project.

When you don't intend to send commands over the wire, you might as well place the command and its command handler in the same file. This makes it really easy to navigate to the handler from a consumer (by pressing F12 in Visual Studio). Tools like Resharper have better code navigation support than VS and they often make it easy to navigate to the implementation without having to place the command and the handler in the same file.

When the project becomes bigger, you might again want to prevent the presentation layer(s) from taking a dependency on the business layer. In that case again the commands and the ICommandHandler(Of T) interface must be in a different assembly. In such project it could be beneficial to again have a 'Contract' assembly that contains interfaces and commands. But again, it all depends on context.

>> Would you split services into commands and handlers and wire up everything using IoC in the client app?

You should certainly not replace all services by commands and handlers; services still have their place in any application and in the applications I build command handlers always depend on other services. But services like OrderServices and CustomerServices will be gone. Those are a big design smell. On the other hand, any logic that two command handlers share, should be extracted into its own service. And of course everything should written using Inversion of Control, or -more specifically- with dependency injection. Whether you use an IoC framework depends on your needs, but you'll soon find out that an IoC container is a really useful tool when you use the command/handler pattern.
Steven (URL) - 02 02 14 - 12:29

Hi Steven - I'm using and liking your query/command architecture. I'm a bit stumped as to how to incorporate file upload/download as part of the service using this architecture. I want to upload a file and store it in SQL Server. It appears the semantics around streaming files to a WCF service require different bindings and contracts. Will I need to create a separate service to handle file streams or can it be incorporated into the CommandHandler. Any pointers would be appreciated.
David Clarke (URL) - 14 02 14 - 00:51

Hi Steven, the articles for commands and queries are one of the best I have red in the past year. Thank you!

My question is should one use commands to perform the standard crud operation like Save? Generally save could be an method in the repository of the aggregate root that could be called from some domain services or directly from the controller. I imagine that we could have a save command that calls the save method of the corresponding repository an probably we could create generic SaveCommandHandler that can be inherited when needed to add some specific functionality. Am I on the right track?
Ivaylo Dimov (URL) - 13 03 14 - 15:21

Hi Ivaylo, it depends on what you're trying to achieve whether this is useful or not. In general I would say that the command/handler pattern is not a replacement of the repository pattern. If your command handlers contain one line of code to map to the repository it might be a useless abstraction, and it might be better to directly inject a repository in the consumer.

On the other hand, using commands for CRUD operations does allow you to have a single abstraction to deal with in case communication goes through a web service (see one of my later articles about Highly Maintainable WCF Services for instance). That's what we did in a precious project. We used generic GetByIdQuery(Of TEntity) query and SaveOrUpdateCommand(Of TEntity) command to simulate CRUD operations. On the client we hid those commands and queries behind a IRepository(Of TEntity) interface, but that abstraction did not exist on the server.
Steven (URL) - 13 03 14 - 15:45

This is one of the best blog posts I've read in a long time (and the next post on queries is even better!). It pre dates posts by Rob Conery and Ayende on the same theme. I just don't know why some devs won't let the repository pattern go.

Thank you for sharing this
DalSoft (URL) - 03 05 14 - 00:44


No trackbacks:

Trackback link:

Please enable javascript to generate a trackback url


  
Remember personal info?

/

Before sending a comment, you have to answer correctly a simple question everyone knows the answer to. This completely baffles automated spam bots.
 

  (Register your username / Log in)

Notify:
Hide email:

Small print: All html tags except <b> and <i> will be removed from your comment. You can make links by just typing the url or mail-address.