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:
public void Should_connect_delete_handler()
var container = new WindsorContainer();
.BasedOn(typeof(IHandler<>)).WithService.Base()); // [a]
var handler = container.Resolve<IHandler<DeleteEntityCommand<Customer>>>();
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)
var closedDeleteCommandType = openDeleteCommandType.MakeGenericType(type);
var closedHandlerInterfaceType = openHandlerInterfaceType.MakeGenericType(closedDeleteCommandType);
var closedDeleteCommandHandlerType = openDeleteCommandHandlerType.MakeGenericType(type);
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: