Вопрос по c#, dependency-injection – Касл Виндзор: Как мне внедрить все реализации интерфейса в ctor?

20

Я написал интерфейс, который реализован несколькими классами. Я хочу написать класс Service, в котором все зарегистрированные реализации будут внедрены в его ctor.

Единственное решение, которое я могу придумать, - это вызвать Service Locator внутри 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();
        }
    }
}

EDIT - Я должен упомянуть, что я использую Замок Виндзор.

Ваш Ответ

4   ответа
3

но я просто хотел добавить к этому небольшую дополнительную складку: вы должны добавить суб-резольверBEFORE Вы регистрируете свои компоненты.

Это будет работать:

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

Это будетNOT Работа

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));
Error: User Rate Limit Exceeded
26

CollectionResolver, Проверь этоЗамок Виндзор FAQ:

Windsor, by default when you have dependency on IFoo[], IEnumerable or IList will check if you have a component registered for that exact type (array or list of IFoo), not if you have any components registered for IFoo (array of components, is not the same as a component which is an array). You can change the behavior to say "When you see array or list of IFoo just give me all IFoos you can get" you use CollectionResolver.

Прямая ссылка на Castle Resolvers:Resolvers.

20

что на этот вопрос уже дан ответ, но я подумал, что пример добавления 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>()
);
Error: User Rate Limit Exceeded
14

хотя мне все еще не хватало, как зарегистрировать все реализации данного интерфейса.

Надеюсь это поможет!

container.Register(
            Classes.FromAssemblyContaining<IVehicle>()
                .BasedOn<IVehicle>().WithService.FromInterface()
            );
Error: User Rate Limit Exceeded

Похожие вопросы