Wednesday, January 6, 2010

Castle Windsor: Order Matters

I've been learning a lot about Castle Windsor lately. I ran into something that surprised me yesterday. Suppose you have the following class hierarchy:
interface Service
{
}

class ServiceA : Service
{
}

class ServiceB : Service
{
}
What do you think the output from this code will be?
var container = new WindsorContainer();

container.Register(Component
    .For<Service>()
    .ImplementedBy<ServiceA>());
container.Register(Component
    .For<Service>()
    .ImplementedBy<ServiceB>()
    .Named("serviceb"));

var service = container.Resolve<Service>();

Console.WriteLine(service.GetType().Name);
If you said ServiceA, then you were right! Now, what about the output from this code?
var container = new WindsorContainer();

container.Register(Component
    .For<Service>()
    .ImplementedBy<ServiceB>()
    .Named("serviceb"));
container.Register(Component
    .For<Service>()
    .ImplementedBy<ServiceA>());

var service = container.Resolve<Service>();

Console.WriteLine(service.GetType().Name);
If you said ServiceB, then maybe the title of this post gave the answer away. I expected the named service to be a special case. In other words, I thought asking for a Service implementation would always give me ServiceA, unless I specifically asked for ServiceB by name.

3 comments:

  1. This is a very powerful feature of Windsor. You don't have to do anything explicit in order to mark an implementation as 'default'. It's also great for decorator chains (where ServiceB itself has a dependency on Service).

    ReplyDelete
  2. Wow, my team has always used ServiceOverrides for creating decorator chains, this is much easier. Thanks!

    ReplyDelete
  3. Nice Post, thanks for the info!

    ReplyDelete