Enterprise Library IContainerConfigurator implementation for Windsor

May 15, 2011 | Castle Windsor

Alternative title: “Error Management Is Sometimes Exceptionally Difficult, Part 2”

I previously tried to write an implementation of the IContainerConfigurator interface. The most tricky part was extracting the container registration entry for constructing a specific type. The entry is provided in the TypeRegistration class as a LambdaExpression and additional metadata.

The fact that EnterpriseLibraryContainer class is completely decoupled from a specific container implementation made me keep trying to figure out a way to get the entries from the LamdaExpressions.

I posted two questions on StackOverflow, and I got all the necessary info:

The support I had from the project team members  was accurate and detailed. That was great.

The current implementation relies heavily on Windsor’s Property classes and it is based on the UnityContainerConfigurator.

Below is the WindsorParameterVisitor,

private sealed class WindsorParameterVisitor : ParameterValueVisitor
{
    public Property[] InjectionParameters { get; private set; }

    protected override void VisitConstantParameterValue(
         ConstantParameterValue parameterValue)
    {
        string key = ((MemberExpression)parameterValue.Expression).Member.Name;
        InjectionParameters = new Property[] 
        {
             Property.ForKey(key).Eq(parameterValue.Value) 
        };
    }

    protected override void VisitResolvedParameterValue(
         ContainerResolvedParameter parameterValue)
    {
        InjectionParameters = new Property[] 
        {
             Property.ForKey(parameterValue.Type).Is(parameterValue.Name) 
        };
    }

    protected override void VisitEnumerableParameterValue(
         ContainerResolvedEnumerableParameter parameterValue)
    {
        InjectionParameters = parameterValue.Names
           .Select(name => Property.ForKey(parameterValue.ElementType).Is(name))
           .ToArray();
    }
}

The ParameterValueVisitor class is needed because most TypeRegistrations are quite complex coming with both ConstructorParameters and InjectedProperties and all this stuff must be routed on the .DependsOn() method of Windsor (actually Castle.MicroKernel).

Below is some basic setup for configuring the Enterprise Library to use Windsor,

var container = new WindsorContainer();

// Add a SubResolver for components with IEnumerable<T> dependencies on .ctors.
container.Kernel.Resolver.AddSubResolver(
     new CollectionResolver(container.Kernel));

// This is the Windsor specific impl. of IContainerConfigurator interface.
var configurator = new WindsorContainerConfigurator(container);

// Configure the Enterprise Library Container to use Windsor internally.
EnterpriseLibraryContainer.ConfigureContainer(configurator, 
    ConfigurationSourceFactory.Create());

// Set Current property to a new instance of the WindsorServiceLocator adapter.
EnterpriseLibraryContainer.Current = new WindsorServiceLocator(container);

The source can be found here.

This is tested with Exception Handling application block and I was able to resolve the ExceptionManager class.