我在应用程序中使用Castle Windsor 2.5。我有一个服务,它是一种复合物,充当实现相同接口的对象的分发者。

public interface IService { void DoStuff(string someArg); }

public class ConcreteService1 : IService {
    public void DoStuff(string someArg) { }
}

public class ConcreteService2 : IService {
    public void DoStuff(string someArg) { }
}

public class CompositeService : List<IService>, IService
{
    private readonly IService[] decoratedServices;

    CompositeService(params IService[] decoratedServices) {
        this.decoratedServices = decoratedServices;
    }

    public void DoStuff(string someArg) {
        foreach (var service in decoratedServices) {
            service.DoStuff(someArg);
        }
    }
}


我遇到的问题是,使用如下所示的config导致Windsor报告“尝试解析依赖项时检测到一个循环”。

windsor.Register(
    Component
        .For<IService>()
        .ImplementedBy<CompositeService>(),

    Component
        .For<IService>()
        .ImplementedBy<ConcreteService1>(),

    Component
        .For<IService>()
        .ImplementedBy<ConcreteService2>()
);


这种循环行为似乎与可用于使装饰器样式强壮的标准(基于非集合)行为不一致,在该行为中,将忽略要解析的组件,而改用实现相同接口的下一个注册组件。

因此,我想知道的是,在解决CompositeService属性的IService服务时,是否有一种方法可以使Windsor排除decoratedServices组件。 decoratedServices属性应包含两个项目:ConcreteService1的实例和ConcreteService2的实例。我想在不显式指定依赖项的情况下执行此操作。

最佳答案

我了解Unity,但我相信您的问题是一个普遍的问题,涉及所有DI系统。
大多数DI工具都具有明确命名依赖项的功能。如果要实现相同的接口,则此功能特别有用。

因此,我相信您的问题不是依赖性的圆性(如果有这样的话),而是依赖性的多重性。因此,我将明确命名依赖项如下:

windsor.Register(
Component
    .For<IService>()
    .ImplementedBy<CompositeService>("CompositeService"),

Component
    .For<IService>()
    .ImplementedBy<ConcreteService1>("ConcreteService1"),

Component
    .For<IService>()
    .ImplementedBy<ConcreteService2>("ConcreteService2")


);

但是我看不到您的DI框架如何处理CompositeService的构造函数。 params是一个艰难的过程。

这是我会做的:

1)删除参数2)将构造函数更改为IEnumerable<IService> decoratedServices 3)创建另一个类并实现IEnumerable,这只是工厂将向我返回已定义类型的列表,这些类型将使用它们的名称进行初始化。

关于c# - 如何使用CaSTLe Windsor的CollectionResolver避免循环行为?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3734371/

10-11 02:00