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 >

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

本文代码

你可能感兴趣的:(Converter)