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

Aru*_*run 5 .net c# 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);
   }
}
Run Code Online (Sandbox Code Playgroud)

配置详情如下:

<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>
Run Code Online (Sandbox Code Playgroud)

我的调用代码如下所示:

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

这工作正常,但是一旦我给这个类型命名如下:

<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>
Run Code Online (Sandbox Code Playgroud)

即使我使用明确注册类型,上面的调用代码也不起作用

container.RegisterType<ILogger, NullLogger>();
Run Code Online (Sandbox Code Playgroud)

我收到错误:

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

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

ILogger nullLogger = container.Resolve<ILogger>("NullLogger");
Run Code Online (Sandbox Code Playgroud)

这种行为记录在哪里?

阿伦

er-*_*r-v 5

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

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

  • 它返回T的实例,如果它可以构造或
  • 如果不能,则例外
    • 在接口的情况下
    • 或者当类没有构造函数时,
    • 或者unity不能解析此类构造函数的参数

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

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

ILogger nullLogger = container.Resolve<ILogger>("NullLogger");
Run Code Online (Sandbox Code Playgroud)

作品.

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