Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Castle Windsor: How do I inject all implementations of interface into a ctor?

I've written an interface which is implemented by multiple classes. I want to write a Service class which will have all the registered implementations injected into its ctor.

The only solution I can think of is to call the Service Locator within the ctor and ask it to Resolve() all implementations.

Ideally I would like something like this -

interface IVehicle {     void Start(); }  class Car : IVehicle {     public void Start()     {         Console.WriteLine("Car started.");     } }  class Truck : IVehicle {     public void Start()     {         Console.WriteLine("Truck started.");     } }  class Motorbike : IVehicle {     public void Start()     {         Console.WriteLine("Motorbike started.");     } }  class VehicleService {     // How do I inject all implementations of IVehicle?     public VehicleService(IEnumerable<IVehicle> vehicles)     {         foreach (var vehicle in vehicles)         {             vehicle.Start();         }     } } 

EDIT - I should mention I'm using Castle Windsor.

like image 433
jameskind Avatar asked May 04 '12 15:05

jameskind


2 Answers

You have to use CollectionResolver. Check this Castle Windsor FAQ:

Windsor, by default when you have dependency on IFoo[], IEnumerable or IList will check if you have a component registered for that exact type (array or list of IFoo), not if you have any components registered for IFoo (array of components, is not the same as a component which is an array). You can change the behavior to say "When you see array or list of IFoo just give me all IFoos you can get" you use CollectionResolver.

Direct link to Castle Resolvers: Resolvers.

like image 108
empi Avatar answered Sep 21 '22 15:09

empi


I know this has already been answered, but I thought an example of how to add the CollectionResolver would be useful, so here it is.

Call AddSubResolver before registering the components in the container, e.g.

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

Register the components as normal:

container.Register(     Component.For<IVehicle>().ImplementedBy<Car>(),     Component.For<IVehicle>().ImplementedBy<Truck>(),     Component.For<IVehicle>().ImplementedBy<Motorbike>() ); 
like image 24
Stephen Oberauer Avatar answered Sep 20 '22 15:09

Stephen Oberauer