LYWILL设计运营 - 网站运营与推广、开发技术、成功项目展示。

Spring.NET简易的依赖注入框架

        本文是对《一个简易的IoC框架》的延伸,实现带参数构造函数对象的实例和属性的注入 。
  我们知道可以通过反射获取类的构造函数及参数(GetConstructors方法);可以获取属性和属性的类型(GetProperties方法)。通过
Activator的CreateInstance(Type type, params object[] args)方法可以创建带参数构造函数的实例。通过SetValue方法可以给属性赋值,这样一来,我们就上次的代码稍加改造就可以实现属性的注入了。


  下面是完成的代码:

C#代码
  1. public class Person   
  2. {   
  3.     public string Name { getset; }   
  4.     public int Age { getset; }   
  5. }  

C#代码
  1. public class PersonDao   
  2. {   
  3.     private int intProp;   
  4.   
  5.     public PersonDao(int intProp)   
  6.     {   
  7.         this.intProp = intProp;   
  8.     }   
  9.   
  10.     public Person Entity { getset; }   
  11.   
  12.     public override string ToString()   
  13.     {   
  14.         return "构造函数参数intProp为:" + this.intProp;   
  15.     }   
  16. }  
C#代码
  1. public class ObjectFactory   
  2. {   
  3.     private IDictionary<stringobject> objectDefine = new Dictionary<stringobject>();   
  4.   
  5.     private ObjectFactory(string fileName)   
  6.     {   
  7.         InstanceObjects(fileName);  // 实例IoC容器   
  8.         DiObjects(fileName);  // 属性注入   
  9.     }   
  10.   
  11.     private static ObjectFactory instance;   
  12.   
  13.     private static object lockHelper = new object();   
  14.   
  15.     public static ObjectFactory Instance(string fileName)   
  16.     {   
  17.         if (instance == null)   
  18.         {   
  19.             lock (lockHelper)   
  20.             {   
  21.                 instance = instance ?? new ObjectFactory(fileName);   
  22.             }   
  23.         }   
  24.         return instance;   
  25.     }   
  26.   
  27.     /// <summary>   
  28.     /// 实例IoC容器   
  29.     /// </summary>   
  30.     /// <param name="fileName"></param>   
  31.     private void InstanceObjects(string fileName)   
  32.     {   
  33.         XElement root = XElement.Load(fileName);   
  34.         var objects = from obj in root.Elements("object")   
  35.                       select obj;   
  36.   
  37.         //无参构造函数   
  38.         objectDefine = objects.Where(obj =>   
  39.             obj.Element("constructor-arg") == null).ToDictionary(   
  40.                 k => k.Attribute("id").Value,    
  41.                 v =>    
  42.                 {   
  43.                     string typeName = v.Attribute("type").Value;     
  44.                     Type type = Type.GetType(typeName);     
  45.                     return Activator.CreateInstance(type);   
  46.                 }   
  47.             );   
  48.   
  49.         //有参构造函数   
  50.         foreach (XElement item in objects.Where(obj =>    
  51.             obj.Element("constructor-arg") != null))   
  52.         {                                                                                                                                                     
  53.             string id = item.Attribute("id").Value;   
  54.             string typeName = item.Attribute("type").Value;   
  55.             Type type = Type.GetType(typeName);   
  56.             var args = from property in type.GetConstructors()[0].GetParameters()   
  57.                        join el in item.Elements("constructor-arg")   
  58.                        on property.Name equals el.Attribute("name").Value   
  59.                        select Convert.ChangeType(el.Attribute("value").Value,   
  60.                        property.ParameterType);   
  61.             object obj = Activator.CreateInstance(type, args.ToArray());   
  62.             objectDefine.Add(id, obj);   
  63.         }   
  64.     }   
  65.   
  66.     /// <summary>   
  67.     /// 属性注入   
  68.     /// </summary>   
  69.     /// <param name="fileName"></param>   
  70.     private void DiObjects(string fileName)   
  71.     {   
  72.         XElement root = XElement.Load(fileName);   
  73.         var objects = from obj in root.Elements("object")   
  74.                       select obj;   
  75.   
  76.         foreach (KeyValuePair<string,object> item in objectDefine)   
  77.         {   
  78.             foreach (var el in objects.Where(e =>    
  79.                 e.Attribute("id").Value == item.Key).Elements("property"))   
  80.             {   
  81.                 Type type = item.Value.GetType();   
  82.                 //获取属性   
  83.                 foreach (PropertyInfo property in type.GetProperties())   
  84.                 {   
  85.                     if (property.Name == el.Attribute("name").Value)   
  86.                     {   
  87.                         if (el.Attribute("value") != null)   
  88.                         {   
  89.                             //设置属性值   
  90.                             property.SetValue(item.Value,    
  91.                                 Convert.ChangeType(el.Attribute("value").Value,    
  92.                                 property.PropertyType), null);   
  93.                         }   
  94.                         else if (el.Attribute("ref") != null)   
  95.                         {   
  96.                             object refObject = null;   
  97.   
  98.                             if (objectDefine.ContainsKey(el.Attribute("ref").Value))   
  99.                             {   
  100.                                 refObject = objectDefine[el.Attribute("ref").Value];   
  101.                             }   
  102.                             //设置关联对象属性   
  103.                             property.SetValue(item.Value, refObject, null);   
  104.                         }   
  105.                     }   
  106.                 }   
  107.             }   
  108.         }   
  109.     }   
  110.   
  111.     /// <summary>   
  112.     /// 获取对象   
  113.     /// </summary>   
  114.     /// <param name="id"></param>   
  115.     /// <returns></returns>   
  116.     public object GetObject(string id)   
  117.     {   
  118.         object result = null;   
  119.   
  120.         if (objectDefine.ContainsKey(id))   
  121.         {   
  122.             result = objectDefine[id];   
  123.         }   
  124.   
  125.         return result;   
  126.     }   
  127. }  
XML/HTML代码
  1. <?xml version="1.0" encoding="utf-8" ?>  
  2.   
  3. <objects>  
  4.   
  5.   <object id="person" type="SpringNetMyDi.Person, SpringNetMyDi">  
  6.     <!--属性值类型注入-->  
  7.     <property name="Name" value="lywill"/>  
  8.     <property name="Age" value="29"/>  
  9.   
  10.   </object>  
  11.   
  12.   <object id="personDao" type="SpringNetMyDi.PersonDao, SpringNetMyDi">  
  13.     <!--构造器注入-->  
  14.     <constructor-arg name="intProp" value="1"/>  
  15.   
  16.     <property name="Entity" ref="person" />  
  17.        
  18.   </object>  
  19.   
  20. </objects>  
C#代码
  1. class Program   
  2. {   
  3.     static void Main(string[] args)   
  4.     {   
  5.         ObjectFactory factory = ObjectFactory.Instance(@"D:\我的文档\桌面\springnetalldemo1\SpringNet_Lesson9\SpringNetMyDi\Objects.xml");   
  6.   
  7.         PersonDao dao = (PersonDao)factory.GetObject("personDao");   
  8.   
  9.         Console.WriteLine("姓名:" + dao.Entity.Name);   
  10.         Console.WriteLine("年龄:" + dao.Entity.Age);   
  11.         Console.WriteLine(dao);   
  12.   
  13.         Console.ReadLine();   
  14.     }   
  15. }  

  

输入结果: