Castle Windsor and child containers: Revolutions

Continuing the topic from the previous posts.

What would happen?

Current behavior of Windsor is somewhat flawed. What it will do is it will resolve foo, and provide it with bar. The flaw of this behavior is that now when we resolve foo via any of the tree containers we’ll  get the same instance (since it’s a singleton). This introduced two issues:

  • component from childA (bar) will now be available via childB and parent while logically thinking – it should not.
  • we have temporal coupling in our code. Depending on the order of containers we’ll use to resolve foo we’ll get different results

So what should happen?

Ok, so now that we agreed that current behavior is indeed flawed (we did, didn’t we?) what are our options for fixing it? We basically have two options (both of which were mentioned in comments to previous post).

It all boils down to scoping. If we have a per-web-request object – should single instance be shared among multiple containers or should it be per-web-request-and-per-container? If we have singleton should it be single instance per container, per container hierarchy or per process?

Let’s consider slightly more complicated picture.

containers_2

Now we have two components for bar, one in childA and one in parent. Also we have one more component; baz, which is registered in childB.

classes_2

Baz has dependency on foo, foo still has dependency on bar. All of these dependencies are optional, and all components are singletons.

There can only be one

We want to scope instances strictly per their container. So that foo is scoped in parent (thus visible from its child containers as well), and bar is scoped per childA. This appears to be the simplest setup, and the most in line with definition of singleton, but then we run into problems outlined above.

We then could add another constraint – dependencies can only face upwards the container hierarchy. We would then get foo with its dependency on bar pulled from parent container, consistently, regardless of the container we’d resolve it from. Moreover, we could resolve baz from childB and its dependency would be properly populated from parent since it comes from a container that is higher in the hierarchy, so we’re safe to pull that dependency.

On the other hand this robs us of one of nice (and often used) side effect of child containers, that is contextual overriding of components from containers higher up the hierarchy.

If we have bar in childA, we’d expect to get foo pulled via childA to have that bar, not parent’s bar.

Or perhaps not?

We can approach the problem from another angle altogether. We can narrow down the scope of a component instance, to the scope of its outermost dependency. What do I mean by that?

When resolving foo from childA the outermost dependency of foo would be the bar living in childA. Therefore the instance of foo would have bar pulled from parent, but scoped in childA. Therefore when we’d request foo again, but this time from childB we’d get another instance of foo, with dependency on bar pulled from parent. This could potentially lead to problems as well, since if you’re depending on the fact that single instance of your component will ever live in the application at given point in time you may end up with problems.

So what do you think? Which approach would you prefer, or is there something I’m missing here?

To those who though I’m seriously going to remove support for nested containers rest assured this is not going to happen. I still think this could be a viable option and I wanted to throw it into the air, but its become such a core feature of each IoC container, that Windsor would look crippled if it didn’t have it, regardless of whether or not it’d be actually needed.

Castle Windsor and Child containers reloaded

This is a follow up to my previous post. I deliberately didn’t discuss the issues that arise when using container hierarchies to get some feedback on usage first.

So what’s the problem?

Consider trivial scenario:

two

We have two components, where foo depends on bar. The dependency is optional, which means that foo can be constructed even when bar is not available.

Then we have the following container hierarchy:

one

We have parent container where foo is registered and two child containers. In one of them we register bar. Both foo and bar are singletons (for sake of simplicity – the example would work for any non-transient lifestyle).

Now we do this

var fooA = childA.Resolve<Foo>();

var fooB = childB.Resolve<Foo>();

What should happen?

Castle Windsor and child containers

Neal started looking into behaviour of child containers in Windsor. This is an area that’s very rarely used, and as Hammett wrote two years ago – this is speaking with the devil himself. No one really ever uses it so it never got well defined and as Neal found out there are certain inconsistencies, and grey areas there.

This was a don’t ask, don’t tell area, and since Neil opened that can of worms, it’s time to deal with the issue. I’m considering several solutions, and the one I’m leaning towards most would be probably the most controversial.

Remove support for child containers altogether?

Basically handler selectors and sub-resolvers give you all the power you need to handle scenarios where you would want to use child container instead. I think removing the child containers, and add some nicer support for contextual scoping of components would be the best solution.

The point of this post however is to get your thoughts on this issue. Are you using child containers in Windsor? What are you using it for? How are you using it? Write a comment or if you don’t want to share that in public just drop me an email. I’d really like to get a clean picture of how usage of this feature looks like at this point in time, before I make a decision.

Contextual controller injection in ASP.NET MVC with Castle Windsor

I chatting the other day with Chris Canal, who played with reimplementing piece of code Jimmy Bogard put on his blog using Castle Windsor.

While I’m not an ASP.NET MVC expert by no means, I decided to give it a go and try to do it myself. See Jimmy’s post first to get the context, as I’m only going to talk about the code.

The code here uses development build of Windsor (what will become version 2.5) and does not work with version 2.1

No child container

Jimmy used child container to scope the contextual dependencies. While this is also possible using Windsor, it feels like using shotgun to kill a fly. We can use contextual meta-components that will have the sole purpose of scoping our RequestContext and ControllerContext and achieve the same effect as if we were using child container, only this is far more lightweight.

public class ControllerContextHost

{

    private ControllerBase controller;

 

    public void SetController( ControllerBase controller )

    {

        if( controller != null )

        {

            throw new InvalidOperationException( "Controller was already set!" );

        }

        this.controller = controller;

 

    }

 

    public ControllerContext GetContext()

    {

        if( controller == null )

        {

            return null;

        }

        return controller.ControllerContext;

    }

}

 

public class RequestContextHost

{

    private RequestContext context;

    public void SetContext( RequestContext context )

    {

        if( context != null )

        {

            throw new InvalidOperationException( "Context was already set!" );

        }

        this.context = context;

    }

    public RequestContext GetContext()

    {

        if( context == null )

        {

            throw new InvalidOperationException( "Context was not set!" );

        }

        return context;

    }

}

Having that we can now simply use the hosts to cache their respective components. We set the RequestContext in ControllerFactory.

public IController CreateController( RequestContext requestContext, string controllerName )

{

    var host = this.container.Resolve<RequestContextHost>();

    host.SetContext( requestContext );

    return container.Resolve<IController>( controllerName );

}

Registration

ControllerContext has a twist. Since we register controllers as transient, we have to pass the controller to ControllerContextHost right after it gets created. We use OnCreate method for that.

public void Install(IWindsorContainer container, IConfigurationStore store)

{

    container.Register(AllTypes.FromAssemblyContaining<HomeController>()

                            .BasedOn<IController>()

                            .Configure(x => x.LifeStyle.Transient

                                                    .Named(GetControllerName(x.Implementation))

                                                    .OnCreate((k, c) => k.Resolve<ControllerContextHost>()

                                                                            .SetController(c as ControllerBase))));

}

It is also important how we register the services:

public void Install( IWindsorContainer container, IConfigurationStore store )

{

    container.Register( Component.For<ControllerContextHost>().LifeStyle.PerWebRequest,

                        Component.For<RequestContextHost>().LifeStyle.PerWebRequest,

                        Component.For<RequestContext>()

                            .UsingFactoryMethod( k => k.Resolve<RequestContextHost>().GetContext() ),

                        Component.For<HttpContextBase>()

                            .UsingFactoryMethod( k => k.Resolve<RequestContext>().HttpContext ),

                        Component.For<Func<ControllerContext>>()

                            .UsingFactoryMethod<Func<ControllerContext>>(

                                k => k.Resolve<ControllerContextHost>().GetContext ) );

}

Both hosts are registered as per web request since that’s how we want to cache the contexts they host. We’re only going to use the hosts internally and not expose them. Hence we register the contexts via UsingFactoryMethod. We also don’t register the ControllerContext directly, but rather via Func delegate, to break cyclic dependency between ControllerContext and Controller.

Now we only need to register the remaining services we want to use:

public void Install( IWindsorContainer container, IConfigurationStore store )

{

    container.Register(

        Component.For<IFoo>().ImplementedBy<Foo>().LifeStyle.Transient,

        Component.For<IActionInvoker>().ImplementedBy<ControllerActionInvoker>().LifeStyle.Transient,

        Component.For<ITempDataProvider>().ImplementedBy<SessionStateTempDataProvider>().LifeStyle.Transient,

        Component.For<RouteCollection>().Instance( RouteTable.Routes ),

        Component.For<UrlHelper>().LifeStyle.Transient );

}

and we’re free to take dependency on IFoo, which has dependency on our contextual services. Just for completeness, here’s code registering all the components in the container:

this._windsorContainer = new WindsorContainer()

    .Install( FromAssembly.This() );

And now, assuming I didn’t mis-translate Jimmy’s StructureMap code, out application should work just like his sample.

Advanced Castle Windsor – generic typed factories, auto-release and more

This post is a playground for me, to try out some ideas I want to include in my talk about Windsor at KGD.NET meeting later this month.

Scenario

We have a messaging application built around two interfaces:

public interface Command

{

}

 

public interface Handler

{

    void Execute();

}

 

public interface Handler<T> : Handler where T : Command

{

    T Command { get; set; }

}

Hopefully I don’t have to explain how they work. The idea is, application receives commands from somewhere, then it pulls all handlers registered for this command and let them handle the command. Split of Handler interface into generic and non-generic part is there to make up for lack of co/contra-variance in .NET 3.5.

Commands and Handlers

Handlers are quite simple classes implementing closed version of Handler<> interface. For example to change client’s address we’d have the following command

[Serializable]

public class UpdateClientCorrespondenceAddressCommand : Command

{

    private readonly AddressDto address;

    private readonly Guid clientId;

 

    public UpdateClientCorrespondenceAddressCommand(Guid clientId, AddressDto address)

    {

        this.clientId = clientId;

        this.address = address;

    }

 

    public AddressDto Address

    {

        get { return address; }

    }

 

    public Guid ClientId

    {

        get { return clientId; }

    }

}

and its handler:

public class UpdateClientCorrespondenceAddressHandler : Handler<UpdateClientCorrespondenceAddressCommand>

{

    private readonly Repository<Client> clientRepository;

 

    public UpdateClientCorrespondenceAddressHandler(Repository<Client> clientRepository)

    {

        this.clientRepository = clientRepository;

    }

 

    public UpdateClientCorrespondenceAddressCommand Command { get; set; }

 

    public void Execute()

    {

        var command = Command;

        if (command == null) return;

 

        var client = clientRepository.Get(command.ClientId);

        client.ChangeCorrespondenceAddress(command.Address);

        clientRepository.Update(client);

    }

}

Nothing earth shattering here. We would have similar set up for other business events in the application. We assume we can have more than one handler for single command (for example another handler would update shipping costs and promotions available for the new address of the client).

The ability to pull multiple services from the container via typed factory is not available in Windsor 2.1.1 – you need the trunk version to take advantage of it.

Registration

To register the code we create an installer:

public class Installer : IWindsorInstaller

{

    public void Install(IWindsorContainer container, IConfigurationStore store)

    {

        container.AddFacility<TypedFactoryFacility>()

            .Register(

                Component.For<ITypedFactoryComponentSelector>().ImplementedBy<HandlerSelector>(),

                Component.For<AutoReleaseHandlerInterceptor>(),

                AllTypes.FromAssemblyContaining<Program>()

                    .BasedOn(typeof(Repository<>))

                    .WithService.Base()

                    .Configure(c => c.LifeStyle.Singleton)

                    .BasedOn(typeof(Handler<>))

                    .WithService.Base()

                    .Configure(c => c.LifeStyle.Is(LifestyleType.Transient)

                                        .Interceptors<AutoReleaseHandlerInterceptor>()),

                Component.For<HandlerFactory>().AsFactory());

    }

}

There are a couple interesting things here. First we register typed factory facility, which we’ll use later on to pull handlers for commands we receive. Then we register custom selector for typed factory (discussed below), and an interceptor (discussed below). Then we  register all repositories and all handlers from given assembly, configuring handlers with transient lifestyle and with the interceptor we registered above. Lastly we also register typed factory for handlers:

public interface HandlerFactory

{

    Handler[] GetHandlersForCommand(Command command);

}

Typed factory selector

The handler factory has to do quite a lot of work for us. Given an instance of a command, it has to pull from the container all the handlers for the command’s type. To do this we need to use a custom selector (and trunk version of Windsor).

public class HandlerSelector:ITypedFactoryComponentSelector

{

    public TypedFactoryComponent SelectComponent(MethodInfo method, Type type, object[] arguments)

    {

        Debug.Assert(arguments.Length == 1);

        var message = arguments[0];

        var handlerType = typeof(Handler<>).MakeGenericType(message.GetType());

        return new TypedFactoryComponentCollection(handlerType.MakeArrayType(), new Arguments(arguments));

    }

}

Based on the command’s type we create closed Handler<> type and return TypedFactoryComponentCollection (new type that pulls all components for given service) passing down the command as typed argument to the resolution.

Putting it all together

We can now use the code like this:

private static void Main()

{

    using(var container = new WindsorContainer().Install(new Installer()))

    {

        var factory = container.Resolve<HandlerFactory>();

 

        DoActualWork(factory);

        Console.ReadKey(true);

    }

}

 

private static void DoActualWork(HandlerFactory factory)

{

    var command = ImmitateCommandArrived();

 

    var handlers = factory.GetHandlersForCommand(command);

    foreach (var handler in handlers)

    {

        handler.Execute();

    }

}

 

private static Command ImmitateCommandArrived()

{

    return new UpdateClientCorrespondenceAddressCommand(Guid.NewGuid(), GetSomeAddress());

}

Notice how simple the calling code is. It has no knowledge of the (quite complex) process that takes place behind the scenes to create strongly typed instances of appropriate classes. It does not even know what actual type of command it got.

What about releasing transient handlers?

Isn’t this code too simple though? It resolves handlers, which are transient components and it does not release them. And we all know transient components need to be released in Windsor, right?

Well – it does release them actually, it just doesn’t do it explicitly. Remember we registered an interceptor with all handlers. Here’s how that interceptor looks like:

[Transient]

public class AutoReleaseHandlerInterceptor : IInterceptor

{

    private static readonly MethodInfo Execute = typeof(Handler).GetMethod("Execute");

    private readonly IKernel kernel;

 

    public AutoReleaseHandlerInterceptor(IKernel kernel)

    {

        this.kernel = kernel;

    }

 

    public void Intercept(IInvocation invocation)

    {

        if(invocation.Method!=Execute)

        {

            invocation.Proceed();

            return;

        }

 

        try

        {

            invocation.Proceed();

        }

        finally

        {

            kernel.ReleaseComponent(invocation.Proxy);

        }

    }

}

The interceptor releases the component after the call to Execute for us. Thanks to this we take the burden (no pun intended) of releasing the components from the callers, and we make sure our handlers won’t leak memory. This is quite a useful trick actually, and while I have precisely zero knowledge of NServiceBus, I think it could be used to fix the issue Davy discussed, without having to mess with release policy.

New Castle Windsor feature – typed arguments

With Windsor 2.1.1 out the door, we’re already working on version 3.0 (and looking for your feedback and ideas for the next version!). Yesterday I committed first “big” feature that probably will make it to the release.

DISCLAIMER:

All the code shown here represents a work in progress. Keep in mind that final version may be different. This also means that any feedback on this feature is appreciated.

Named Arguments

In current version of Windsor you can define inline dependencies for a component in at least three different ways:

  • When registering it (with value obtained at registration time):
    container.Register(

        Component.For<ICustomer>()

            .ImplementedBy<CustomerImpl>()

            .DependsOn(

                Property.ForKey("Name").Eq("Caption Hook"),

                Property.ForKey("Address").Eq("Fairyland"),

                Property.ForKey("Age").Eq(45)

                )

            );

  • When registering it (with value obtained at resolution time), AKA – Dynamic Parameters
    container.Register(

        Component.For<ClassWithArguments>()

            .LifeStyle.Transient

            .DynamicParameters((k, d) =>

            {

                d["timeStamp"] = DateTime.Now;

                d["user"] = Thread.CurrentPrincipal.Identity;

            })

        );

  • When resolving it (although this is something you should strive to avoid, using constructor injection and/or Typed factory facility)
  • var component = container.Resolve<ClassWithArguments>(new

    {

        TimeStamp = DateTime.Now,

        User = Thread.CurrentPrincipal.Identity

    });

What all these approaches have in common is that you specify dependency by name. Windsor when resolving the component will then use the value you provided for constructor arguments or settable properties with that name it finds on the component. What if you don’t care about the name?

Typed Arguments

Trunk version of Windsor lets you do just that – omit the name in which case Windsor will use the type of the argument as the sole information when building your component.

container.Register(

       Component.For<ClassWithArguments>()

           .Lifestyle.Transient

           .DependsOn(

              Property.ForKey<DateTime>().Eq(DateTime.Now),

              Property.ForKey<IIdentity>().Eq(Thread.CurrentPrincipal.Identity))

    );

As you can see here we use the type as the key for the dependency. This works also with dynamic parameters as well as when passing arguments straight from the call site. A new class – Arguments has been introduced to accommodate this new feature (although ordinal Hashtable or Dictionary<object,object> will do just fine as well) .

container.Resolve<ClassWithArguments>(

    new Arguments(new object[]

    {

        DateTime.Now,

        Thread.CurrentPrincipal.Identity

    })

);

The Arguments class itself implements IDictionary and can wrap either another IDictionary containing either named or typed arguments, anonymous type containing named arguments or array of objects to be used as typed arguments. It is advised to use this type when you plan to use typed arguments.

Additionally to help you deal with filling the dictionaries in more usable fashion an extension method on IDictionary (so they work for Arguments type as well) called Insert (with few overloads) has been introduced. It lets you insert arguments in a fluent, more user friendly fashion.

container.Register(

    Component.For<ClassWithArguments>()

    .DynamicParameters((k, d) =>

        d.Insert(DateTime.Now)

        .Insert(Thread.CurrentPrincipal.Identity))

    );

Final words

While this may be appealing at first to use typed arguments everywhere, resist the temptation unless you have a good reason. Named arguments should always be your first choice. Name is a valuable contextual information that may improve the readability of your code. Windsor will favor named arguments over typed and use the latter only if it can’t find a matching named argument.

Transparently releasing components in Windsor

Disclaimer:

This post is about the idea, not about the implementation. The implementation is crippled, not thread safe, will work only in few scenarios and only if used properly. Do not copy and blindly use this code.

The problem

One of unique features of Windsor is that it manages the lifecycle of objects it creates for you. What this means (among other things) is that it will dispose all disposable objects it instantiates. However to do this, it has to keep a reference to these components. Also that means that in order to properly release the components you have to get hold of the container and once you’re done using the components – explicitly release them with the container.

It may be not desirable from your perspective to do it like this. Ideally, you’d rather use your component, call Dispose and then have Windsor release the component. This is not quite possible, since there’s no way by which Windsor can be notified that your component was disposed. Or is there?

The idea

Since Dispose is an interface method and Windsor has quite powerful AOP capabilities, we can take advantage of that and intercept the call to Dispose and transparently release our component. Let’s build a disposable component first:

public interface IController : IDisposable

{

    int DoSomething();

 

    bool Disposed { get; set; }

}

 

public class Controller : IController

{

    // notice it's not virtual!

    public void Dispose()

    {

        // some clean up logic here

        Disposed = true;

    }

 

    public int DoSomething()

    {

        return 42;

    }

 

    public bool Disposed

    {

        get; set;

    }

}

One important thing to notice about this code – Dispose is not implemented virtually. This will make our sample simpler since we won’t have to deal with recursion.

Then we set up the stage:

[TestFixture]

public class TransparentReleasingTest

{

    private WindsorContainer container;

 

    [SetUp]

    public void SetUp()

    {

        container = new WindsorContainer();

        container.Register(Component.For<ReleaseComponentInterceptor>());

        container.Register(Component.For<IController>().ImplementedBy<Controller>()

                               .LifeStyle.Transient

                               .Interceptors<ReleaseComponentInterceptor>());

    }

 

    [TearDown]

    public void CleanUp()

    {

        container.Dispose();

    }

}

We’ll discuss the ReleaseComponentInterceptor, which is the gist of this post, in a minute. Let’s first create a test:

[Test]

public void Dispose_releases_component()

{

    IController item;

    using (var controller = container.Resolve<IController>())

    {

        item = controller;

        controller.DoSomething();

 

        Assert.IsTrue(container.Kernel.ReleasePolicy.HasTrack(controller));

        Assert.IsFalse(controller.Disposed);

    }

 

    Assert.IsFalse(container.Kernel.ReleasePolicy.HasTrack(item));

    Assert.IsTrue(item.Disposed);

}

Notice that in order for the interceptor to intercept the call to Dispose we need to cast component to IDisposable before calling the method (‘using’ will do that for us). Notice important aspect of this test – it is completely container agnostic. It does not need any kind of explicit nor indirect reference to the container to work and to release the component properly. Let’s now see what happens behind the scenes.

Interceptor

The hero of the day, is the following interceptor:

[Transient]

public class ReleaseComponentInterceptor : IInterceptor

{

    private static readonly MethodInfo dispose = typeof(IDisposable).GetMethods().Single();

    private readonly IKernel kernel;

 

    public ReleaseComponentInterceptor(IKernel kernel)

    {

        this.kernel = kernel;

    }

 

    public void Intercept(IInvocation invocation)

    {

        if (invocation.Method == dispose)

        {

            kernel.ReleaseComponent(invocation.Proxy);

        }

        else

        {

            invocation.Proceed();

        }

    }

}

Most of the time it just sits there and does nothing. However if it detects a call to Dispose, it releases the component from the container, which will in turn invoke the Dispose again (this time on the class, not interface, and since the interface is implemented non-virtually that second call won’t be intercepted), perform all other decommission job for the component as well as all its dependencies and it will release it, so that it can be garbage collected afterwards.

This is just another useful trick, worth knowing if you want to keep your design container agnostic while still reaping full benefits it provides.

Castle Windsor 2.1, Dynamic Proxy 2.2 and more released!

Update: Due to a regression error discovered in Windsor Factory Support Facility, we decided to act fast and provide updated package of Windsor, without the issue. Get it here. Sorry for the inconvenience.

Castle Project

What better way of starting a new year can there be, than fresh set of releases from Castle Project?!

Core 1.2 (with more)

Castle Core 1.2 has now its own, separate package. Since the beta few things have changed

  • Email sender component is now integrated with Core, so if you were using it, you now should look for it in Castle.Core.dll. The version shipped with Core 1.2 has the following major breaking changes:
    – Removed Message, MessageAttachment and MessageAttachmentCollection classes and replaced them with MailMessage, Attachment and AttachmentCollection from .NET classes in System.Net.Mail
  • Logging services (integration of Castle’s logging abstraction with log4net and NLog) is now packaged with Core. Notice that these are dependent on Core (just like it used to be). Castle does not have dependency on any of these, so don’t freak out.
  • few minor bugs were fixed, but nothing serious. You should be able to just switch the reference to new version and start using it with no changes to your code.
  • We ship four versions: for .NET 2.0, for .NET 3.5, for Silverlight 3.0 and for Mono 2.6

Get it here.

Dynamic Proxy 2.2

This is a pretty significant release. If you haven’t before, read what we had in beta. Since then, the following has changed

  • Interface members on proxies are behaving almost identical to version 2.1 (change from beta). That means that they take long name of explicit implementation (InterfaceName.Method() instead of Method()), only if you already have a method called Method() on your proxy, either from base class or other interface. And even then, it will still be public, which makes it more transparent to the user.
  • We ship three versions: for .NET 2.0 (this is the last version to support .NET 2.0), .NET 3.5 and Silverlight 3.0

Get it here.

MicroKernel/Windsor 2.1.1 (with support for Silverlight)

Probably the biggest thing about this release is that it includes a Silverlight version. There are a couple more highlights thought

  • revamped typed factory facility
  • added ability to specify Type Forwarding via XML config with the following syntax:
    <component

      id="hasForwards"

      type="Castle.MicroKernel.Tests.ClassComponents.TwoInterfacesImpl, Castle.MicroKernel.Tests"

      service="Castle.MicroKernel.Tests.ClassComponents.ICommon, Castle.MicroKernel.Tests">

      <forwardedTypes>

        <add service="Castle.MicroKernel.Tests.ClassComponents.ICommon2, Castle.MicroKernel.Tests" />

      </forwardedTypes>

    </component>

  • added DynamicParameters (with additional option to return delegate to be called upon component’s destruction)
  • added OnCreate method, which lets you act upon component after it’s created, and before it’s removed (see this Tehlike’s post. Notice it’s not in a facility now, so it just works out of the box.)
  • added lazy component loader
  • major performance improvements in certain scenarios
  • and many bugfixes, see commit log for full list if you’re interested
  • We ship two versions: for .NET 3.5 and for Silverlight 3.0
  • There is also logging facility included in the package. Again – neither MicroKernel, nor Windsor depend on it, so don’t freak out.

Get it here.

We’re already gathering ideas for the next version, so go ahead to the Castle UserVoice page and tell us, what you’d like to see in the next version!

Advanced Castle Windsor: custom registration conventions for partially closed types

Jimmy published very interesting post about generic registration of certain partially closed types in StructureMap container. Go read the entire post first, it’s really worth it.

You’re back? OK. Jimmy uses StructureMap container in his sample, and after I saw it I immediately thought about doing the same thing in Windsor. That’s what this post is all about – how to make the following test pass:

Test

[Test]

public void Should_connect_delete_handler()

{

    var container = new WindsorContainer();

    container.AddFacility<HandlerFacility>();

    container.Register(AllTypes.FromAssemblyContaining<DeleteCustomerCommand>()

                        .BasedOn<IEntity>()

                        .BasedOn(typeof(IHandler<>)).WithService.Base()); // [a]

 

    var handler = container.Resolve<IHandler<DeleteEntityCommand<Customer>>>();

    Assert.IsInstanceOf<DeleteEntityCommandHandler<Customer>>(handler);

}

Solution

The line marked with [a] registers types implementing IHandler<>. It will register DeleteEntityCommandHandler<> with IHandler<>.  This is the equivalent of StructureMap’s ConnectImplementationToTypesClosing in Windsor.

As you can see I also registered a facility – HandlerFacility which does the actual magic, and is unsurprisingly quite similar to Jimmy’s DeleteCommandRegistrationConvention.

public class HandlerFacility : AbstractFacility

{

    private static readonly Type openDeleteCommandType = typeof(DeleteEntityCommand<>);

    private static readonly Type openHandlerInterfaceType = typeof(IHandler<>);

    private static readonly Type openDeleteCommandHandlerType = typeof(DeleteEntityCommandHandler<>);

 

    protected override void Init()

    {

        Kernel.HandlerRegistered += OnHandlerRegistered;

    }

 

    private void OnHandlerRegistered(IHandler handler, ref bool statechanged)

    {

        var type = handler.ComponentModel.Implementation;

        if (type.IsAbstract || typeof(IEntity).IsAssignableFrom(type) == false)

        {

            return;

        }

 

        var closedDeleteCommandType = openDeleteCommandType.MakeGenericType(type);

        var closedHandlerInterfaceType = openHandlerInterfaceType.MakeGenericType(closedDeleteCommandType);

        var closedDeleteCommandHandlerType = openDeleteCommandHandlerType.MakeGenericType(type);

 

        Kernel.Register(

            Component.For(closedHandlerInterfaceType)

                .ImplementedBy(closedDeleteCommandHandlerType)

                .LifeStyle.Transient);

    }

}

Just to set the record straight – you don’t really need a facility for that .You could hook an anonymous delegate to container kernel’s event and do that work inline. Having a facility is however my preferred solution since it encapsulates the work nicely, and gives you access to configuration, provided you’d ever want to externalize some part of the facility.

That’s all we needed to make the test pass:

sshot-1

Learning in the open – Sample application for Castle stack

We’re getting really close to new release of major Castle Project elements (Monorail 2.0, ActiveRecord 2.1, Windsor 2.1…). Coincidently I started building a small application on top of the stack, and I thought it would be a good idea to make this a “learning in the open” experience, and share my progress on this blog.

This will mostly (at least initially) be a rework of Ayende’s old series, but I will update it to the latest version of the projects and try to discuss some new features as we go along.

I don’t have the application ready yet. This is a journey for me, and as I don’t really have much experience with either Monorail or ActiveRecord, I may do stupid things. That’s the part where your feedback comes into play. I want to drive this series on feedback in much greater degree than the series on Dynamic Proxy. If you want me to dive into details on certain topics – let me know. If you think I should have done something differently and revisit some parts – let me know.

That’s all for now – see you next time.