我有一个简单的控制台应用程序,我有以下设置:
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");
这种行为记录在哪里?
阿伦
答案 0 :(得分:5)
如您所知 - 有两种类型的实例:命名(可以是其中许多)和默认(只有一种可以,并且没有名称)
Resolve() - 不查看命名实例 - 它只查找默认值,如果没有默认实例
让我们来看看你的例子。第一个问题,简单的问题 - 为什么在配置中指向名称时代码停止工作。 答案是因为现在没有为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