Home > General > Castle Windsor – resolving collections

Castle Windsor – resolving collections

Although I’ve used Castle Windsor on many projects, I often forget that Windsor does not automatically resolve dependencies that are a collection.

public class Demo
{
	private readonly IPrinter[] printers;

	public Demo(IPrinter[] printers)
	{
		this.printers = printers;
	}
}

Trying to call the Resolve method on the class above will throw an exception:

Castle.MicroKernel.Handlers.HandlerException: Can't create component 'CollectionResolverDemo.Demo' as it has dependencies to be satisfied.

'CollectionResolverDemo.Demo' is waiting for the following dependencies:
- Service 'CollectionResolverDemo.IPrinter[]' which was not registered.

Before registering components, we need to add a dependency resolver that can handle arrays, lists, and other collections:

container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel));

It is important to add the collection resolver before registering components. If the resolver is added after the component registration, collections will not be resolved correctly and the same exception will be thrown.

container.Register(Component.For<Demo>());
container.Register(Component.For<IPrinter>().ImplementedBy<RedPrinter>());
container.Register(Component.For<IPrinter>().ImplementedBy<GreenPrinter>());
container.Register(Component.For<IPrinter>().ImplementedBy<BluePrinter>());

// Bad
container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel));

One strange behavior that I’ve noticed is that if I add the collection resolver in the middle of my registration:

container.Register(Component.For<Demo>());
container.Register(Component.For<IPrinter>().ImplementedBy<RedPrinter>());
container.Register(Component.For<IPrinter>().ImplementedBy<GreenPrinter>());

container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel));

container.Register(Component.For<IPrinter>().ImplementedBy<BluePrinter>());

I would expect that BluePrinter would be the only printer that is passed to the Demo class. However, this is not the case. Instead, the entire collection of IPrinters is resolved correctly.

  1. October 17, 2014 at 8:12 pm

    I like what you guys are usually up too. This kind of clever work and reporting!

    Keep up the awesome works guys I’ve included you guys to blogroll.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: