我编写了一个由多个类实现的接口。我想写一个Service类,它将所有注册的实现注入到它的ctor中。
我能想到的唯一解决方案是在ctor中调用服务定位器并要求它解决()所有实现。
理想情况下,我想要这样的事情 -
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();
}
}
}
编辑 - 我应该提到我正在使用Castle Windsor。
答案 0 :(得分:27)
您必须使用CollectionResolver
。检查此Castle Windsor FAQ:
Windsor,默认情况下依赖于IFoo [], IEnumerable或IList将检查您是否有组件 注册了那个确切的类型(IFoo的数组或列表),而不是你 有任何为IFoo注册的组件(组件数组,不是 与作为数组的组件相同)。你可以改变 行为说“当你看到IFoo的数组或列表时,只要给我一切 IFoos你可以得到“你使用CollectionResolver。
直接链接到Castle Resolvers:Resolvers。
答案 1 :(得分:22)
我知道这已经得到了解答,但我认为如何添加CollectionResolver的示例会很有用,所以现在就是这样。
在注册容器中的组件之前调用AddSubResolver,例如
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>()
);
答案 2 :(得分:16)
虽然我仍然缺少如何注册给定接口的所有实现,但发现这个答案很有用。
希望这有帮助!
container.Register(
Classes.FromAssemblyContaining<IVehicle>()
.BasedOn<IVehicle>().WithService.FromInterface()
);
答案 3 :(得分:3)
这里的答案都是正确的,但我只想为它添加一些额外的皱纹:你必须添加子解析器 BEFORE ,你注册你的组件。
这将有效:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="rightcolumn">
some content
</div>
<div id="test">
</div>
<div (click)="addMatter()"> Add Matter </div>
这将不工作
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>()
);