Unity 配置:typeConverter的使用
本文主要介绍自己在使用Unity时碰到的一个问题,及解决方案。
由于本人不擅长写作,所以文字都很简单,各位还是主要看代码及DEMO吧。
首先先看一下以下代码:
public interface ILogger
{
void Write();
}

public class FlatFileLogger : ILogger
{
private Message _message;
public FlatFileLogger(Message message)
{
_message = message;
}

public void Write()
{
Console.WriteLine(String.Format("Message:{0}", _message));
Console.WriteLine("Target:FlatFile");
}
}

public class Message
{
private string _message;
private Message(string message)
{
_message = message;
}

public override string ToString()
{
return _message.ToString();
}

public static Message CreateMessage(string message)
{
return new Message(message);
}
}

class Program
{
static void Main(string[] args)
{
IUnityContainer container = new UnityContainer();
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Containers["containerOne"].Configure(container);

ILogger log = container.Resolve<ILogger>();
log.Write();

Console.ReadLine();
}
}
配置文件:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
Microsoft.Practices.Unity.Configuration, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</configSections>
<unity>
<typeAliases>
<typeAlias alias="string" type="System.String, mscorlib" />

<!-- Lifetime manager types -->
<typeAlias alias="singleton"
type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager,
Microsoft.Practices.Unity" />
<typeAlias alias="external"
type="Microsoft.Practices.Unity.ExternallyControlledLifetimeManager,
Microsoft.Practices.Unity" />

<!-- User-defined type aliases -->
<typeAlias alias="ILogger" type="UnityDemo.ILogger, UnityDemo" />
<typeAlias alias="FlatFileLogger" type="UnityDemo.FlatFileLogger, UnityDemo" />
<typeAlias alias="Message" type="UnityDemo.Message, UnityDemo" />
</typeAliases>
<containers>
<container name="containerOne">
<types>
<type type="ILogger" mapTo="FlatFileLogger"/>
</types>
</container>
</containers>
</unity>
</configuration>
一运行程序就报错,那是因为Message类的构造函数是私有的,Unity无法自动装配。
本来父对象的构造函数如果需要指定具体值,可以通过修改配置文件来达到目的,配置修改如下:
<type type="ILogger" mapTo="FlatFileLogger">
<typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement,
Microsoft.Practices.Unity.Configuration">
<constructor>
<param name="message" parameterType="Message">
<value value="Some Value"></value>
</param>
</constructor>
</typeConfig>
</type>
但现在还有一个问题,就是由于参数message的类型是自定义类型,不是像string, int等系统类型, 按以上配置是无法把一个Message的实例传给FlatFileLogger的构造函数的。这时就需要用到typeConverter,把value中的值转换成一个Message的实例。
LoggerConverter:
public class LoggerConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}

public override object ConvertFrom(ITypeDescriptorContext context,
CultureInfo culture, object value)
{
if (value is string)
{
return Message.CreateMessage(value.ToString());
}
return base.ConvertFrom(context, culture, value);
}
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
Microsoft.Practices.Unity.Configuration, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</configSections>
<unity>
<typeAliases>
<typeAlias alias="string" type="System.String, mscorlib" />

<!-- Lifetime manager types -->
<typeAlias alias="singleton"
type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager,
Microsoft.Practices.Unity" />
<typeAlias alias="external"
type="Microsoft.Practices.Unity.ExternallyControlledLifetimeManager,
Microsoft.Practices.Unity" />

<!-- User-defined type aliases -->
<typeAlias alias="ILogger" type="UnityDemo.ILogger, UnityDemo" />
<typeAlias alias="FlatFileLogger" type="UnityDemo.FlatFileLogger, UnityDemo" />
<typeAlias alias="LoggerConverter" type="UnityDemo.LoggerConverter, UnityDemo" />
<typeAlias alias="Message" type="UnityDemo.Message, UnityDemo" />
</typeAliases>
<containers>
<container name="containerOne">
<types>
<type type="ILogger" mapTo="FlatFileLogger" name="FlatFileLogger" />
<type type="ILogger" mapTo="DatabaseLogger" name="DatabaseLogger"/>
<type type="ILogger" mapTo="FlatFileLogger">
<typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement,
Microsoft.Practices.Unity.Configuration">
<constructor>
<param name="message" parameterType="Message">
<value value="FlatFileLogger" type="Message" typeConverter="LoggerConverter"></value>
</param>
</constructor>
</typeConfig>
</type>
</types>
</container>
</containers>
</unity>
</configuration>
经过修改后,程序终于可以正常运行了。
运行结果:
本文代码
由于本人不擅长写作,所以文字都很简单,各位还是主要看代码及DEMO吧。
首先先看一下以下代码:





















































配置文件:

































一运行程序就报错,那是因为Message类的构造函数是私有的,Unity无法自动装配。
本来父对象的构造函数如果需要指定具体值,可以通过修改配置文件来达到目的,配置修改如下:










但现在还有一个问题,就是由于参数message的类型是自定义类型,不是像string, int等系统类型, 按以上配置是无法把一个Message的实例传给FlatFileLogger的构造函数的。这时就需要用到typeConverter,把value中的值转换成一个Message的实例。
LoggerConverter:





















修改后最终的配置文件:















































经过修改后,程序终于可以正常运行了。
运行结果:

本文代码
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)