命名类型不用于构造函数注入

时间:2010-05-05 07:12:57

标签: c# .net unity-container

我有一个简单的控制台应用程序,我有以下设置:

public interface ILogger
{
   void Log(string message);
}

class NullLogger : ILogger
{
   private readonly string version;

   public NullLogger()
   {
      version = "1.0";
   }
   public NullLogger(string v)
   {
      version = v;
   }
   public void Log(string message)
   {
     Console.WriteLine("NULL> " + version + " : " + message);
   }
}

配置详情如下:

<type type="UnityConsole.ILogger, UnityConsole" mapTo="UnityConsole.NullLogger, UnityConsole">
 <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practices.Unity.Configuration">
   <constructor>
     <param name="message" parameterType="System.String" >
        <value value="2.0" type="System.String"/>
     </param>
   </constructor>
 </typeConfig>

我的调用代码如下所示:

IUnityContainer container = new UnityContainer();
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Containers.Default.Configure(container);
ILogger nullLogger = container.Resolve<ILogger>();
nullLogger.Log("hello");

这很好用,但是一旦我给这个类型命名如下:

<type type="UnityConsole.ILogger, UnityConsole" mapTo="UnityConsole.NullLogger, UnityConsole" name="NullLogger">
 <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practices.Unity.Configuration">
   <constructor>
     <param name="message" parameterType="System.String" >
       <value value="2.0" type="System.String"/>
     </param>
   </constructor>
 </typeConfig>

即使我使用

显式注册类型,上述调用代码也不起作用
container.RegisterType<ILogger, NullLogger>();

我收到错误:

{“依赖项的解析失败,类型= \”UnityConsole.ILogger \“,name = \”\“。异常消息是:当前构建操作(构建密钥构建密钥[UnityConsole.NullLogger,null])失败:尝试调用构造函数UnityConsole.NullLogger(System.String v)时无法解析参数v。(策略类型BuildPlanStrategy,索引3)“}

为什么团结不会查看命名实例?为了让它发挥作用,我将不得不这样做:

ILogger nullLogger = container.Resolve<ILogger>("NullLogger");

这种行为记录在哪里?

阿伦

1 个答案:

答案 0 :(得分:5)

如您所知 - 有两种类型的实例:命名(可以是其中许多)和默认(只有一种可以,并且没有名称)

Resolve() - 不查看命名实例 - 它只查找默认值,如果没有默认实例

  • 如果可以,则返回T的实例 建造或
  • 如果不能,则
  • 例外
    • 如果是接口
    • 或上课时 没有构造函数,
    • 或unity无法解析参数 这种类型的构造函数

让我们来看看你的例子。第一个问题,简单的问题 - 为什么在配置中指向名称时代码停止工作。 答案是因为现在没有为ILogger和Resolve()注册默认实例 - 不查看命名实例 - 它只查找默认实例。

第二个问题为什么在container.RegisterType<ILogger, NullLogger>();之后它不起作用 答案是因为当选择类型的构造函数时,团结是贪婪的。一般来说,它总是需要构造函数,其中参数的数量更大。所以花了这个public NullLogger(string v)无法创建字符串(你可以在内部异常中看到它)。没有关于选择默认分辨率的构造函数的信息。所有信息都是关于命名的。这就是为什么

ILogger nullLogger = container.Resolve<ILogger>("NullLogger");

作品。

此行为记录在帮助中,可以在http://unity.codeplex.com/releases/view/18855下载。或者你可以看看http://msdn.microsoft.com/en-us/library/ff649334.aspx