Thursday, August 20, 2009

Windsor Registration : Service Interface

Sometimes when registering classes on Windsor container, that extend an existing base class with an interface, using auto registration and FirstInterface method is useless, because first interface finds the interface implemented by base class:

[TestFixture]
public class RegistrationFixture : ContainerTest
{
[Test]
public void Can_Find_Service_Using_Interface()
{
var service = TryResolve<IService>();

Assert.That(service, Is.Not.Null);
}

protected override void OnSetup()
{
base.OnSetup();

Container.Register(AllTypes.From(typeof(ServiceImpl))
.Where(null)
.Configure(x => x.LifeStyle.Is(LifestyleType.Transient))
.WithService.FirstInterface());
}

private interface IBaseService
{
}

private interface IService
{
}

private class BaseService : IBaseService
{
}

private class ServiceImpl : BaseService, IService
{
}
}
If you run the test, it will fail, because ServiceImpl is registered with IBaseService interface, which is the first interface on the class hierarchy. But that is not what I intended to do. I wanted the to register it using the first interface on the same type, e.g. IService. Extension methods come to the rescue:
public static class ContainerExtensions
{
public static BasedOnDescriptor FirstInterfaceOnClass(this ServiceDescriptor serviceDescriptor)
{
return serviceDescriptor.Select((t, bt) =>
{
var baseInterfaces = t.BaseType.GetInterfaces();
var interfaces = t.GetInterfaces().Except(baseInterfaces);

return interfaces.Count() != 0 ? new[] {interfaces.First()} : null;
});
}
}
Changing the registration to this would pass the failing test:
Container.Register(AllTypes.From(typeof(ServiceImpl))
.Where(null)
.Configure(x => x.LifeStyle.Is(LifestyleType.Transient))
.WithService.FirstInterfaceOfClass());


Submit this story to DotNetKicks Shout it

No comments: