Can Castle.Windsor使用类型和名称选择构造函数

本文关键字:选择 构造函数 类型 Castle Windsor Can | 更新日期: 2023-09-27 18:27:47

我有一个class

public class Foo
{
    public Foo(string a, string b)
    {
    }
    public Foo(string a, byte[] b)
    {
    }
}

我正在尝试注册Foo并使用public Foo(string a, string b)构造函数。然而,Windsor不会查看传入的值的类型,并选择错误的构造函数。

程序:

class Program
{
    public void Main()
    {
        var container = new WindsorContainer();
        container.Register(Component.For<Foo>()
            .DependsOn(Dependency.OnValue("a", "Bar"))
            .DependsOn(Dependency.OnValue("b", "Baz")));
        // Blows up trying to convert string to byte[]
        var foo = container.Resolve<Foo>();
    }
}

如何帮助Windsor选择正确的构造函数?

请注意,在我的实际代码中,我试图使用Dependency.OnAppSettingsValueApp.Config中提取值。

编辑:

我通过创建一个调用正确构造函数的包装类来解决这个问题。

public class FooInjectionWrapper
{
    public FooInjectionWrapper(string a, string b)
    {
        Foo = new Foo(a, b);
    }
    public Foo Foo { get; private set; }
}

程序:

class Program
{
    public void Main()
    {
        var container = new WindsorContainer();
        container.Register(Component.For<FooInjectionWrapper>()
            .DependsOn(Dependency.OnValue("a", "Bar"))
            .DependsOn(Dependency.OnValue("b", "Baz")));
        container.Register(Component.For<Foo>()
            .UsingFactoryMethod(k => k.Resolve<FooInjectionWrapper>().Foo));
        //Works fine
        var foo = container.Resolve<Foo>();
    }
}

Can Castle.Windsor使用类型和名称选择构造函数

Windsor不支持选择构造函数。Windsor(和其他容器)认为所有构造函数都是相等的。如果一切都相等,那么组件的依赖关系越多,它应该具有的功能就越多。这就是为什么windsor会选择最贪婪的构造函数。如果相等,它将只选择任何构造函数:http://docs.castleproject.org/Windsor.How-constructor-is-selected.ashx

变通办法是使用工厂方法:

container.Register(
    Component.For<Foo>()
             .UsingFactoryMethod(() => new Foo("Bar", "Baz")));

总是可以为字符串类型定义一个值,而不是"b"参数。命名优先于类型,因此可以定义"a"参数,并且可以并行定义字符串类型:

var container = new WindsorContainer();
container.Register(Component.For<Foo>()
    .DependsOn(Dependency.OnValue("a", "Bar"))
    .DependsOn(Dependency.OnValue(typeof(string), "Baz")));