Unity.Resolve如何知道要使用哪个构造函数?

时间:2010-03-18 13:29:11

标签: .net unity-container ioc-container resolve

给定一个包含多个构造函数的类 - 如何告诉Resolve使用哪个构造函数?

考虑以下示例类:

public class Foo
{
    public Foo() { }
    public Foo(IBar bar)
    {
        Bar = bar;
    }
    public Foo(string name, IBar bar)
    {
        Bar = bar;
        Name = name;
    }
    public IBar Bar { get; set; }        
    public string Name { get; set; }
}

如果我想使用Resolve创建一个Foo类型的对象,Resolve将如何知道要使用哪个构造函数?我怎么能告诉它使用正确的呢?假设我有一个注册了IBar的容器 - 它会理解它应该支持构建者采用IBar吗?如果我也指定了一个字符串 - 它会使用(string, IBar)构造函数吗?

Foo foo = unityContainer.Resolve<Foo>(); 

请忽略这样一个事实:如果这个类只有一个构造函数可能会更容易......

2 个答案:

答案 0 :(得分:58)

  

当目标类包含多个构造函数时,Unity将使用具有应用了InjectionConstructor属性的构造函数。如果有多个构造函数,并且没有构造函数携带InjectionConstructor属性,Unity将使用具有最多参数的构造函数。如果有多个这样的构造函数(多于一个具有相同参数数量的“最长”),Unity将引发异常。

取自link text

答案 1 :(得分:32)

注册类型时,可以指定要使用的构造函数:

container.RegisterType<Foo>(
    new InjectionConstructor(
        new ResolvedParameter<IBar>()));

以上代码来自内存,但这是一般原则。在这种情况下,我选择了采用IBar类型的单个参数的构造函数。

  

请忽略这样一个事实:如果这个类只有一个构造函数可能会更容易......

我不能忽视这一点。对于构造函数注入,歧义是一种设计气味。你基本上是在说:我真的不知道我是否关心这种依赖。

当然,Unity可能会为您解决这个问题,但是您将依赖于特定的容器行为,而不是正确设计您的API。 其他容器可能有不同的行为,因此如果您选择从Unity迁移到更好的容器,可能会出现细微的错误。

DI-friendly, but container-agnostic方式编写代码会更安全。