27

我编写了一个由多个类实现的接口。我想编写一个服务类,它将所有注册的实现注入到它的ctor中。

我能想到的唯一解决方案是在 ctor 中调用 Service Locator 并要求它 Resolve() 所有实现。

理想情况下,我想要这样的东西-

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();
        }
    }
}

编辑- 我应该提到我正在使用温莎城堡。

4

4 回答 4

32

你必须使用CollectionResolver. 查看此温莎城堡常见问题解答

Windsor,默认情况下,当您依赖 IFoo[] 时,IEnumerable 或 IList 将检查您是否为该确切类型(数组或 IFoo 列表)注册了组件,而不是是否为 IFoo 注册了任何组件(组件数组,与作为数组的组件不同)。您可以将行为更改为“当您看到 IFoo 的数组或列表时,只需给我您可以获得的所有 IFoos”您使用 CollectionResolver。

直接链接到 Castle Resolvers:Resolvers

于 2012-05-04T16:00:42.370 回答
30

我知道这已经得到了回答,但我认为如何添加 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>()
);
于 2015-03-14T22:01:58.810 回答
20

尽管我仍然想念如何注册给定接口的所有实现,但发现这个答案很有用。

希望这可以帮助!

container.Register(
            Classes.FromAssemblyContaining<IVehicle>()
                .BasedOn<IVehicle>().WithService.FromInterface()
            );
于 2015-12-16T17:30:20.897 回答
3

这里的答案都是正确的,但我只是想给它添加一点额外的皱纹:您必须在注册组件之前添加子解析器。

这将起作用:

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

行不通_

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));
于 2016-09-27T14:26:27.517 回答