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

jam*_*ind 26 c# dependency-injection castle-windsor

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

我能想到的唯一解决方案是在ctor中调用服务定位器并要求它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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑 - 我应该提到我正在使用Castle Windsor.

emp*_*mpi 30

你必须使用CollectionResolver.查看Castle Windsor常见问题解答:

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

直接链接到Castle Resolvers:Resolvers.


Ste*_*uer 27

我知道这已经得到了解答,但我认为如何添加CollectionResolver的示例会很有用,所以现在就是这样.

在注册容器中的组件之前调用AddSubResolver,例如

container = new WindsorContainer();
container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel));
Run Code Online (Sandbox Code Playgroud)

正常注册组件:

container.Register(
    Component.For<IVehicle>().ImplementedBy<Car>(),
    Component.For<IVehicle>().ImplementedBy<Truck>(),
    Component.For<IVehicle>().ImplementedBy<Motorbike>()
);
Run Code Online (Sandbox Code Playgroud)


Cou*_*ero 18

发现这个答案有用虽然我仍然缺少如何注册给定接口的所有实现.

希望这可以帮助!

container.Register(
            Classes.FromAssemblyContaining<IVehicle>()
                .BasedOn<IVehicle>().WithService.FromInterface()
            );
Run Code Online (Sandbox Code Playgroud)