Castle Windsor:如何将所有接口实现注入ctor?

时间:2012-05-04 15:53:59

标签: c# dependency-injection castle-windsor

我编写了一个由多个类实现的接口。我想写一个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。

4 个答案:

答案 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>()
);