Monthly Archives: August 2011

Castle Windsor resolution logic: Cool handler filter that orders components

As you can see from my previous post on handler filters, an IHandlersFilter will have a chance to do stuff to the array of handlers that would otherwise be used untouched during a call to ResolveAll (ResolveAll is also what happens behind the scenes when a component relies on CollectionResolver to supply a collection of components for it to use).

Now, what is left is to implement some kind of logic that does something to the handlers array. First thing that comes to my mind is ordering the handlers!

Ordering the handlers is very relevant e.g. in scenarios where tasks are modeled as a series of steps that should be executed in a consistent fashion. An example could be a component (TaskProcessor) that gets a collection of implementations of some task-like interface injected (IEnumerable<ITask>).

Now, to ensure that this list of tasks is properly ordered, I’d like to specify a few hints on how they should be ordered. Not too little, because otherwise stuff would not work, but I also don’t want to be overly explicit on how the tasks should be ordered.

So I came up with a solution based on two attributes: ExecutesBeforeAttribute and ExecutesAfterAttribute, allowing types to position themselves in relation to other types they know about, and all other types to stay oblivious of what is going on.

One possible usage scenario could look like this, assuming we have modeled some kind of money transfer as a series of steps, each implementing ITask:

public interface ITask
{
    void Execute();
}
 
public class ExecutePayment : ITask { ... }
 
public class ValidateCreditCards : ITask { ... }
 
public class ValidateDebitAccountBalance : ITask { ... }
 
public class ReportWarnings : ITask { ... }
 
public class GenerateReceipt : ITask { ... }

and then a simplistic executor:

public class TaskExecutor
{
    readonly IEnumerable<ITask> tasks;
 
    public TaskExecutor(IEnumerable<ITask> tasks)
    {
        this.tasks = tasks;
    }
 
    public void ExecuteTasks()
    {
        foreach(var task in tasks)
        {
            task.Execute();
        }
    }
}

Now, carrying out a money transfer would consist of having the executor run through this list of discrete tasks, but it’s probably important that the validation occurs before the actual payment, and it probably doesn’t make sense to generate reports before the payment. Therefore, let’s decorate some of the steps:

public class ExecutePayment : ITask { ... }
 
[ExecutesBefore(typeof(ExecutePayment))]
public class ValidateCreditCards : ITask { ... }
 
[ExecutesBefore(typeof(ExecutePayment))]
public class ValidateDebitAccountBalance : ITask { ... }
 
[ExecutesAfter(typeof(ExecutePayment))]
public class ReportWarnings : ITask { ... }
 
[ExecutesAfter(typeof(ExecutePayment))]
public class GenerateReceipt : ITask { ... }

and then make sure we respect them:

var container = new WindsorContainer();
 
// allow collections to be resolved
container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel));
 
// this is the new thing!
container.Kernel.AddHandlersFilter(new RespectOrderDirectivesHandlersFilter(typeof(ITask)));
 
container.Register(AllTypes.FromThisAssembly().BasedOn<ITask>().WithService.Base(),
                    Component.For<TaskExecutor>());

Now, when the container builds a TaskExecutor, it will inject the ITask implementations in the order specified by the attributes. Inside RespectOrderDirectivesHandlersFilter, there’s a HandlerSorter, which is the implementation of the actual sorting algorithm. It builds a directed graph out of components and their dependents, and then it orders the components so that they will be traversed in a way that respects the order specified by the attributes. I’m not an expert on graph algorithms, so I don’t know if my implementation is really really stupid and slow – but I know that a) it works, and b) the ordering is cached, so the algorithm will only run once per set of handlers.

If you want to know more, or perhaps put RespectOrderDirectivesHandlersFilter to use, you can visit the RespectOrderDirectivesHandlersFilter page on GitHub.

Castle Windsor resolution logic: Handler filters

One of the features I’m looking forward to in the upcoming Castle Windsor 3.0 (“Wawel”) release is handler filters! I’m especially looking forward to this feature because it solves a problem I have had quite a few times now, and also because it’s a feature that I’ve contributed to the Windsor project.

Please note that handler filter are NOT available before Windsor 3.0, which will probably be out sometime around middle August 2011.

As you can see, handler selectors is a hook in Resolve that sorts out the situation by choosing one handler among all the available handlers. Pretty much related to this, are handler filters, which is a hook in ResolveAll, that sorts out the situation by choosing and ordering several handlers from all the available handlers. Let’s take a look at a tiny example….

Example: Task processing pipeline

A golden use case for this feature is when you rely on CollectionResolver to inject a collection for you, e.g. in chain of responsibility-like scenarios like so:

public class TaskProcessor
{
    readonly IEnumerable<ITask> tasks;
    readonly IErrorReporter errorReporter;
 
    public TaskProcessor(IEnumerable<ITask> tasks, IErrorReporter errorReporter)
    {
        this.tasks = tasks;
        this.errorReporter = errorReporter;
    }
 
    public void ProcessTasks()
    {
        foreach(var task in tasks)
        {
            try
            {
                task.DoIt();
            }
            catch(SomeDomainException ex)
            {
                errorReporter.ReportErrorProcessingTask(task, ex);
                break;
            }
        }
    }
}

Usually, when doing this kind of task processing, you care about the order in which the tasks are processed. Let’s pretend we have some tasks:

public class FinishTheJob : ITask
{
    public void DoIt()
    {
        Console.WriteLine("Finishing stuff");
    }
}
 
public class PrepareSomething : ITask
{
    public void DoIt()
    {
        Console.WriteLine("Preparing stuff");
    }
}
 
public class CarryItOut : ITask
{
    public void DoIt()
    {
        Console.WriteLine("Carrying out some important logic");
    }
}

and the tasks are registered “dynamically” (allowing us to add new tasks just by dropping new implementations of ITask into the project), like so:

container.Register(AllTypes.FromThisAssembly().BasedOn<ITask>().WithService.Base());

Now, how do we make sure that the PrepareSomething and FinishTheJob tasks are run at the right time, i.e. before and after CarryItOut? Handler filters to the rescue!

Let’s register a handler filter like so:

container.Kernel.AddHandlersFilter(new TaskHandlersFilter());

and the filter is implemented like this:

class TaskHandlersFilter : IHandlersFilter
{
    readonly Dictionary<Type, int> sortOrder = new Dictionary<Type, int>
                                                   {
                                                       {typeof (PrepareSomething), 1},
                                                       {typeof (CarryItOut), 2},
                                                       {typeof (FinishTheJob), 3},
                                                   };
 
    public bool HasOpinionAbout(Type service)
    {
        return service == typeof(ITask);
    }
 
    public IHandler[] SelectHandlers(Type service, IHandler[] handlers)
    {
        // come up with some way of ordering implementations here
        // (cool solution coming up in the next post... ;))
        return handlers
            .OrderBy(h => sortOrder[h.ComponentModel.Implementation])
            .ToArray();
    }
}

Now, when my program does this:

foreach(var task in container.ResolveAll<ITask>())
{
    task.DoIt();
}

I get this output:

Preparing stuff
Carrying out some important logic
Finishing stuff

just as expected, which in turn means that CollectionResolver‘s call to ResolveAll will also yield an ordered list of tasks.

One could also imagine that only certain handlers were returned, thus allowing tenants in multi-tenant scenarios to have different task processing pipelines.

Nifty, huh? In the next post, I will show a simple yet sophisticated way of ordering the handlers in the SelectHandlers method of a handler filter.

Castle Windsor resolution logic: Handler selectors

Do you know what handler selectors are? It’s a way for you to register some logic in Windsor that will choose among all the available handlers when some particular component is resolved.

E.g. if you have a multi-tenant application with multiple implementations of IUserNotifier, let’s call them NotifyUserBySms and NotifyUserByEmail, and you need to make sure that one particular tenant whose employees are equipped with smartphones get notified by email, you can let a handler selector make this selection transparent to the rest of your application by adding a handler selector, like so:

class UserNotificationHandlerSelector : IHandlerSelector
{
    public bool HasOpinionAbout(string key, Type service)
    {
        return service == typeof (IUserNotifier);
    }
 
    public IHandler SelectHandler(string key, Type service, IHandler[] handlers)
    {
        // somehow determine whether employees of current tenant can receive emails
        Console.WriteLine("Does the current tenant' s employees have smartphones? (y/n)");
 
        switch (char.ToLower(Console.ReadKey().KeyChar))
        {
            case 'y':
                return handlers.Single(h => h.ComponentModel.Implementation == typeof (NotifyUserByEmail));
            default:
                return handlers.First(h => h.ComponentModel.Implementation != typeof (NotifyUserByEmail));
        }
    }
}

thus making it possible for all other services to depend on IUserNotifier, not caring under which tenant’s context they’re running.

As you can see, this handler selector only has an opinion when an IUserNotifier is being resolved. And then, when its SelectHandler method is invoked, it gets to choose among all assignable handlers for that particular service type, effectively providing a way to make sure that some particular implementation is used, given some condition (here simulated by some Console.ReadKey() action).

Nifty huh? Only sad thing though, is that handler selectors are not pulled from the container – you have to supply an instance to the kernel, so if you need some services in the selector you need to pull them manually from the container. This can of course be overcome by supplying the handler selector with a reference to the container, allowing it to Resolve stuff at will – just remember – as always – to Release what you Resolve.

This was a short introduction to handler selectors – next post will be about something new, namely handler filters which is a new feature in Windsor 3.0.