Monday, March 29, 2010

Making use of the Command Pattern on Windows Mobile/phone

The Command pattern is a great pattern for abstracting business processes from your implementation code. This pattern is becoming very popular throughout different types of systems. Whether this is MVC thin client, fat clients such as MVP, MVVM.

The Command pattern works really nicely in combination with a IoC container and DI framework that I have talked about before on this blog.

Often it is desirable for a command to take a context or state. A command should only have one method and should only have one role (single responsibility). The interface for a command could look like so:
public interface ICommand<T>
{
void Execute(T context);
}
So our context here is a generic and is defined when the command is registered with the container.

So imagine we have a CRM system that when a customer is registered, we want to send that customer an email to confirm he/she has been setup correctly. You might have a domain model in this case that raises an event that is caught on the middle tier. When this occurs, instead of baking that code into the presenter/controller/business class, you abstract it out into a command. This not only makes your system more readable/maintainable but makes it easier to test too.

So in this case you could have a context class that contains the state such as the Customer domain object like so:
public class EmailCustomerConfirmationContext
{

public EmailCustomerConfirmationContext(Customer customer)
{
Customer = customer;
}

public Customer Customer{get; private set;}
}
Our command might look something like the following:
public class EmailCustomerConfirmationCommand : ICommand<EmailCustomerConfirmationContext>
{
private IEmailAdapter _emailAdapter;

public EmailCustomerConfirmationCommand(IEmailAdapter emailAdapter)
{
//inject dependencies here.
_emailAdapter = emailAdapter;
}

public void Execute(EmailCustomerConfirmationContext context)
{
_emailAdapter.Send(context.Customer);
}
}
Registering the command with the container (Compact Container - see previous posts on using this container) would look something like the following:
container.AddComponent<ICommand<EmailCustomerConfirmationContext>, EmailCustomerConfirmationCommand>();


Very clean approach. Of course the more dependencies you add to the command, the more complex it will become which means harder to test. So sometimes commands can become over complex. Bear this in mind when adopting this pattern.

Executing the command could look something like the following(assuming you are using the service locator):
var command = ServiceLocator.Current.GetInstance<ICommand<TContext>>();
if (!command.IsNull())
{
command.Execute(context);
}
In terms of handling errors etc, this could be handled via events using some sort of event aggregator pattern or the context itself to pass back data so the middle tier can act accordingly.

No comments: