【问题标题】:How does Unity.Resolve know which constructor to use?Unity.Resolve 如何知道使用哪个构造函数?
【发布时间】:2011-01-29 00:45:28
【问题描述】:

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

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

【问题讨论】:

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


    【解决方案1】:

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

    取自link text

    【讨论】:

    • 正是我想要的!我只是装饰了我想用 [InjectionConstructor] 使用的构造函数
    • 这就是可以节省一个周末的答案。定义明确。
    • 我遇到过Unity没有选择参数最多的构造函数的情况。构造函数有两种,一种有1个参数,另一种有4个参数。它选择一个参数,这是为什么呢?有什么想法或想法,或者我应该在哪里检查?
    【解决方案2】:

    当你注册类型时,你可以像这样指定使用哪个构造函数:

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

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

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

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

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

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

    【讨论】:

    • 谢谢!但是我真的需要在容器中注册类型吗?我将使用容器来解析 Foo 的实例,但我不需要 Foo 在容器中。但是我仍然应该使用RegisterType?或者只是因为我有这种特殊需要告诉它使用哪个构造函数?
    • 是的,也不是。正如 ozczecho 所引用的那样,Unity 使用启发式方法来面对歧义来选择构造函数(它会选择具有最多参数的构造函数)。如果你需要它偏离这个算法,你必须明确告诉它。一种方法是应用 InjectionConstructor 属性,另一种方法是在容器中注册它。我个人更喜欢在容器中注册类型,因为这让我的代码与容器无关。如果适用,它还允许不同的容器配置。
    • FWIW,Unity 解析具体类型(即使它们尚未在容器中注册)的能力是它特有的功能。一些容器支持该功能,而另一些则不支持。
    • +1 你是对的,指出歧义是一种设计气味,让我意识到我应该使用参数注入而不是构造函数注入。我尝试两个构造函数的唯一原因是为了可测试性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多