36

给定一个具有多个构造函数的类 - 我如何告诉 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>(); 

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

4

2 回答 2

63

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

取自链接文本

于 2010-03-18T13:33:48.100 回答
35

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

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

上面的代码来自记忆,但这是一般原则。在本例中,我选择了采用 IBar 类型的单个参数的构造函数。

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

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

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

以对DI 友好但与容器无关的方式编写代码要安全得多。

于 2010-03-18T14:09:29.120 回答