Spring.NET学习笔记8——集合类型的注入(基础篇)

我们在第三篇中学习里一个简易的IoC框架。今天我们接着上次的程序,实现带参数构造函数对象的实例和属性的注入 。

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

  下面是完成的代码:
Domain

  1.     public class Person
  2.     {
  3.         public string Name { get; set; }
  4.         public int Age { get; set; }
  5.     }
  6.   public class PersonDao
  7.     {
  8.         private int intProp;
  9.         public PersonDao(int intProp)
  10.         {
  11.             this.intProp = intProp;
  12.         }
  13.         public Person Entity { get; set; }
  14.         public override string ToString()
  15.         {
  16.             return "构造函数参数intProp为:" + this.intProp;
  17.         }
  18.     }
复制代码

ObjectFactory

  1. public class ObjectFactory
  2.     {
  3.         private IDictionary<string, object> objectDefine = new Dictionary<string, object>();
  4.         private ObjectFactory(string fileName)
  5.         {
  6.             InstanceObjects(fileName);  // 实例IoC容器
  7.             DiObjects(fileName);  // 属性注入
  8.         }
  9.         private static ObjectFactory instance;
  10.         private static object lockHelper = new object();
  11.         public static ObjectFactory Instance(string fileName)
  12.         {
  13.             if (instance == null)
  14.             {
  15.                 lock (lockHelper)
  16.                 {
  17.                     instance = instance ?? new ObjectFactory(fileName);
  18.                 }
  19.             }
  20.             return instance;
  21.         }
  22.         /**//// <summary>
  23.         /// 实例IoC容器
  24.         /// </summary>
  25.         /// <param name="fileName"></param>
  26.         private void InstanceObjects(string fileName)
  27.         {
  28.             XElement root = XElement.Load(fileName);
  29.             var objects = from obj in root.Elements("object")
  30.                           select obj;
  31.             //无参构造函数
  32.             objectDefine = objects.Where(obj =>
  33.                 obj.Element("constructor-arg") == null).ToDictionary(
  34.                     k => k.Attribute("id").Value,
  35.                     v =>
  36.                     {
  37.                         string typeName = v.Attribute("type").Value; 
  38.                         Type type = Type.GetType(typeName); 
  39.                         return Activator.CreateInstance(type);
  40.                     }
  41.                 );
  42.             //有参构造函数
  43.             foreach (XElement item in objects.Where(obj =>
  44.                 obj.Element("constructor-arg") != null))
  45.             {                                                                                                                                                 
  46.                 string id = item.Attribute("id").Value;
  47.                 string typeName = item.Attribute("type").Value;
  48.                 Type type = Type.GetType(typeName);
  49.                 var args = from property in type.GetConstructors()[0].GetParameters()
  50.                           join el in item.Elements("constructor-arg")
  51.                           on property.Name equals el.Attribute("name").Value
  52.                           select Convert.ChangeType(el.Attribute("value").Value,
  53.                           property.ParameterType);
  54.                 object obj = Activator.CreateInstance(type, args.ToArray());
  55.                 objectDefine.Add(id, obj);
  56.             }
  57.         }
  58.         /**//// <summary>
  59.         /// 属性注入
  60.         /// </summary>
  61.         /// <param name="fileName"></param>
  62.         private void DiObjects(string fileName)
  63.         {
  64.             XElement root = XElement.Load(fileName);
  65.             var objects = from obj in root.Elements("object")
  66.                           select obj;
  67.             foreach (KeyValuePair<string,object> item in objectDefine)
  68.             {
  69.                 foreach (var el in objects.Where(e =>
  70.                     e.Attribute("id").Value == item.Key).Elements("property"))
  71.                 {
  72.                     Type type = item.Value.GetType();
  73.                     //获取属性
  74.                     foreach (PropertyInfo property in type.GetProperties())
  75.                     {
  76.                         if (property.Name == el.Attribute("name").Value)
  77.                         {
  78.                             if (el.Attribute("value") != null)
  79.                             {
  80.                                 //设置属性值
  81.                                 property.SetValue(item.Value,
  82.                                     Convert.ChangeType(el.Attribute("value").Value,
  83.                                     property.PropertyType), null);
  84.                             }
  85.                             else if (el.Attribute("ref") != null)
  86.                             {
  87.                                 object refObject = null;
  88.                                 if (objectDefine.ContainsKey(el.Attribute("ref").Value))
  89.                                 {
  90.                                     refObject = objectDefine[el.Attribute("ref").Value];
  91.                                 }
  92.                                 //设置关联对象属性
  93.                                 property.SetValue(item.Value, refObject, null);
  94.                             }
  95.                         }
  96.                     }
  97.                 }
  98.             }
  99.         }
  100.         /**//// <summary>
  101.         /// 获取对象
  102.         /// </summary>
  103.         /// <param name="id"></param>
  104.         /// <returns></returns>
  105.         public object GetObject(string id)
  106.         {
  107.             object result = null;
  108.             if (objectDefine.ContainsKey(id))
  109.             {
  110.                 result = objectDefine[id];
  111.             }
  112.             return result;
  113.         }
  114.     }
复制代码

App.config

  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <objects>
  3.   <object id="person" type="SpringNetMyDi.Person, SpringNetMyDi">
  4.     <!--属性值类型注入-->
  5.     <property name="Name" value="Liu Dong"/>
  6.     <property name="Age" value="27"/>
  7.   </object>
  8.   <object id="personDao" type="SpringNetMyDi.PersonDao, SpringNetMyDi">
  9.     <!--构造器注入-->
  10.     <constructor-arg name="intProp" value="1"/>
  11.     <property name="Entity" ref="person" />
  12.    
  13.   </object>
  14. </objects>
复制代码

Program

  1.   class Program
  2.     {
  3.         static void Main(string[] args)
  4.         {
  5.             ObjectFactory factory = ObjectFactory.Instance(@"F:\Exercise\SpringNet\Step1\SpringNet_Lesson9\SpringNetMyDi\Objects.xml");
  6.             PersonDao dao = (PersonDao)factory.GetObject("personDao");
  7.             Console.WriteLine("姓名:" + dao.Entity.Name);
  8.             Console.WriteLine("年龄:" + dao.Entity.Age);
  9.             Console.WriteLine(dao);
  10.             Console.ReadLine();
  11.         }
  12.     }
复制代码

输入结果:

posted @ 2011-03-26 20:55  似水流年-johnhuo  阅读(184)  评论(0编辑  收藏  举报