0

我想将 Castle Windsor 配置为创建两个相同类型的组件(Foo -> IFoo),但具有不同的构造函数输入。稍后我还想在创建另一个组件时使用这两个组件(类型 Bar - 请参见下面的代码)。

public interface IFoo { }

public class Foo : IFoo
{
    private string _prop;

    public Foo(string prop)
    {
        _prop = prop;            
    }
}

public class Bar
{
    private IFoo _fooAbc;
    private IFoo _foo123;

    public Bar(IFoo fooAbc, IFoo foo123)
    {
        _foo123 = foo123;
        _fooAbc = fooAbc;
    }
}

在组件安装程序中,我尝试注册这样的组件:

public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(Classes.FromThisAssembly()
                            .BasedOn<IFoo>().WithServiceBase()
                            .ConfigureFor<Foo>(c => c.DependsOn(Dependency.OnValue<string>("abc")).Named("fooAbc"))
                            .ConfigureFor<Foo>(c => c.DependsOn(Dependency.OnValue<string>("123")).Named("foo123")));

        container.Register(Component.For<Bar>());   //?? specify which service to use
    }

但是城堡抛出了一个注册异常。那么如何配置 Foo 的两个实例,一个具有“abc”,另一个具有“123”依赖项?此外,我稍后想在构造 Bar 时正确分配它们,以便将 fooAbc 用作第一个构造函数输入,将 foo123 用作第二个。我的最终目标是成功解决 Bar.

4

1 回答 1

1

我不确定这是否更接近您的要求,但是,您可以使用 ServiceOverride.ForKey指定哪些参数映射到哪些名称:

Component.For<Bar>().ImplementedBy<Bar>().
    DependsOn(ServiceOverride.ForKey("fooAbc").Eq("abc")).
    DependsOn(ServiceOverride.ForKey("foo123").Eq("123"))
);

或者,不是直接的答案,但您可以选择解决IEnumerable<IFoo>. 如果您实际上有任意数量的IFoo要解决,这是一个不错的选择。

如果您更改 Bar 的定义以接受IEnumerable

public class Bar
{
    private readonly IEnumerable<IFoo> _foos;

    public Bar(IEnumerable<IFoo> foos)
    {
        _foos = foos;
    }
}

然后注册并解决。在进行注册之前,您需要添加 Resolve。

var container = new WindsorContainer();

container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel, true));

container.Register(
    Component.For<IFoo>().Instance(new Foo("abc")).Named("abc"),
    Component.For<IFoo>().Instance(new Foo("123")).Named("123"),
    Component.For<Bar>().ImplementedBy<Bar>());
于 2013-06-02T20:57:19.303 回答