c# - Castle Windsor: ¿Cómo inyecto todas las implementaciones de interfaz en un ctor?
dependency-injection castle-windsor (4)
Encontré esta respuesta útil, aunque todavía faltaba cómo registrar todas las implementaciones de una interfaz determinada.
¡Espero que esto ayude!
container.Register(
Classes.FromAssemblyContaining<IVehicle>()
.BasedOn<IVehicle>().WithService.FromInterface()
);
He escrito una interfaz que es implementada por varias clases. Quiero escribir una clase de servicio que tenga todas las implementaciones registradas inyectadas en su ctor.
La única solución que se me ocurre es llamar al Localizador de servicios dentro del ctor y pedirle que resuelva () todas las implementaciones.
Idealmente, me gustaría algo como esto:
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();
}
}
}
EDITAR - Debo mencionar que estoy usando Castle Windsor.
Las respuestas aquí son todas correctas, pero solo quería agregarle un poco más de arrugas: debe agregar el sub-resolutor ANTES de registrar sus componentes.
Esto funcionará:
container = new WindsorContainer();
container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel));
container.Register(
Component.For<IVehicle>().ImplementedBy<Car>(),
Component.For<IVehicle>().ImplementedBy<Truck>(),
Component.For<IVehicle>().ImplementedBy<Motorbike>()
);
Esto NO funcionará
container = new WindsorContainer();
container.Register(
Component.For<IVehicle>().ImplementedBy<Car>(),
Component.For<IVehicle>().ImplementedBy<Truck>(),
Component.For<IVehicle>().ImplementedBy<Motorbike>()
);
container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel));
Sé que esto ya ha sido respondido, pero pensé que sería útil un ejemplo de cómo agregar CollectionResolver, así que aquí está.
Llame a AddSubResolver antes de registrar los componentes en el contenedor, por ejemplo
container = new WindsorContainer();
container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel));
Registre los componentes como de costumbre:
container.Register(
Component.For<IVehicle>().ImplementedBy<Car>(),
Component.For<IVehicle>().ImplementedBy<Truck>(),
Component.For<IVehicle>().ImplementedBy<Motorbike>()
);
Tienes que usar CollectionResolver
. Revisa estas preguntas frecuentes sobre Castle Windsor :
Windsor, de manera predeterminada, cuando dependes de IFoo [], IEnumerable o IList comprobará si tienes un componente registrado para ese tipo exacto (matriz o lista de IFoo), no si tienes algún componente registrado para IFoo (matriz de componentes, no es lo mismo que un componente que es una matriz). Puedes cambiar el comportamiento para que diga "Cuando ves una matriz o una lista de IFoo, solo dame todos los IFoos que puedas obtener" usas CollectionResolver.
Enlace directo a Castle Resolvers: Resolvers .