【问题标题】:Unity not using the default constructor of the classUnity不使用类的默认构造函数
【发布时间】:2011-03-09 22:38:00
【问题描述】:

我有这门课:

public class Repo
{
   public Repo() : this(ConfigurationManager.AppSettings["identity"],       ConfigurationManager.AppSettings["password"])

    {

    }

   public Repo(string identity,string password)
   {
       //Initialize properties.
   }

}

我在 web.config 中添加了一行,以便 Unity 容器自动构建此类型。

但在我的应用程序执行期间,我收到此错误消息:

  "System.InvalidOperationException : the parameter identity could not be resolved when attempting to call constructor Repo(String identity, String password)  -->Microsoft.Practices.ObjectBuilder2.BuildFailedException : The current Build operation ...."

1) 为什么 Unity 不使用默认构造函数?

2) 假设我希望 Unity 使用第二个构造函数(参数化的构造函数),我该怎么做 通过配置文件将该信息传递给 Unity ?

【问题讨论】:

    标签: c# .net inversion-of-control unity-container


    【解决方案1】:

    Unity 默认选择参数最多的构造函数。您必须明确告诉 Unity 使用不同的。

    一种方法是使用 [InjectionConstructor] 属性,如下所示:

    using Microsoft.Practices.Unity;
    
    public class Repo
    {
       [InjectionConstructor]
       public Repo() : this(ConfigurationManager.AppSettings["identity"], ConfigurationManager.AppSettings["password"])
       {
    
       }
    
       public Repo(string identity,string password)
       {
           //Initialize properties.
       }
    }
    

    第二种方法是,如果您反对使用属性混淆类/方法,则在使用 InjectionConstructor 配置容器时指定要使用的构造函数:

    IUnityContainer container = new UnityContainer();
    container.RegisterType<Repo>(new InjectionConstructor());
    

    来自documentation

    Unity 如何解析目标构造函数和参数

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

    【讨论】:

    • @IanWarburton 如果你解释你尝试了什么,你看到了什么,我会尽力帮助你解决问题。
    • 嗯,很高兴知道!不知何故,我希望它用最少的参数调用构造函数......有趣
    • 为什么 Unity 不选择 default 构造函数作为它的 default?我也没有多大意义......
    • @talles 这只是我根据文档的“何时使用构造函数注入”部分来猜测选择具有最多参数的构造函数的意图。他们提出的一点是,人们使用构造函数参数来清楚地指示类的依赖关系。选择参数最多的另一个原因是人们可能需要在构造时对其进行初始化,因为该字段不会有为其创建的属性或方法。
    • 在我看来,使用具有最多参数的构造函数是一个荒谬的决定。当我使用的第三方库类使用额外的构造函数进行扩展时,我遇到了一个问题,我更新了库,然后,bam,我的代码被破坏了。
    【解决方案2】:

    尝试以这种方式注册类型:

    <register type="IRepo" mapTo="Repo">
      <constructor />
    </register>
    

    由于constructor 元素中没有指定param 元素,它应该调用默认构造函数。

    您也可以在代码中进行此注册:

    container.RegisterType<IRepo, Repo>(new InjectionConstructor());
    

    【讨论】:

    • 最佳答案!这解决了问题,之前的评论只是解释了默认行为。
    【解决方案3】:

    我有一个更简单的问题导致了这个错误。

    我使用的容器错误的容器。我不小心创建了两个不同的容器,而我的 container.RegisterType 位于正在使用的另一个容器中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-28
      • 2011-06-26
      • 1970-01-01
      • 2011-04-12
      相关资源
      最近更新 更多