码迷,mamicode.com
首页 > 编程语言 > 详细

Spring.Net学习笔记十(打造简易的依赖注入框架)

时间:2015-08-06 16:35:45      阅读:113      评论:0      收藏:0      [点我收藏+]

标签:

      之前我们学习里一个简易的IoC框架。今天我们接着上次的程序,实现带参数构造函数对象的实例和属性的注入 。原文地址:http://www.cnblogs.com/GoodHelper/archive/2009/11/02/SpringNet_MyDi.html

      我感觉这个很有必要对应IOC框架的理解,知道注入的工作原理,对应实际的应用是很有帮助的。

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

  下面是完成的代码:

技术分享
技术分享    public class Person
技术分享    {
技术分享        public string Name { get; set; }
技术分享        public int Age { get; set; }
技术分享    }
技术分享
技术分享   public class PersonDao
技术分享    {
技术分享        private int intProp;
技术分享
技术分享        public PersonDao(int intProp)
技术分享        {
技术分享            this.intProp = intProp;
技术分享        }
技术分享
技术分享        public Person Entity { get; set; }
技术分享
技术分享        public override string ToString()
技术分享        {
技术分享            return "构造函数参数intProp为:" + this.intProp;
技术分享        }
技术分享    }


 

技术分享
技术分享public class ObjectFactory
技术分享    {
技术分享        private IDictionary<string, object> objectDefine = new Dictionary<string, object>();
技术分享
技术分享        private ObjectFactory(string fileName)
技术分享        {
技术分享            InstanceObjects(fileName);  // 实例IoC容器
技术分享            DiObjects(fileName);  // 属性注入
技术分享        }
技术分享
技术分享        private static ObjectFactory instance;
技术分享
技术分享        private static object lockHelper = new object();
技术分享
技术分享        public static ObjectFactory Instance(string fileName)
技术分享        {
技术分享            if (instance == null)
技术分享            {
技术分享                lock (lockHelper)
技术分享                {
技术分享                    instance = instance ?? new ObjectFactory(fileName);
技术分享                }
技术分享            }
技术分享            return instance;
技术分享        }
技术分享
技术分享        /// <summary>
技术分享        /// 实例IoC容器
技术分享        /// </summary>
技术分享        /// <param name="fileName"></param>
技术分享        private void InstanceObjects(string fileName)
技术分享        {
技术分享            XElement root = XElement.Load(fileName);
技术分享            var objects = from obj in root.Elements("object")
技术分享                          select obj;
技术分享
技术分享            //无参构造函数
技术分享            objectDefine = objects.Where(obj =>
技术分享                obj.Element("constructor-arg") == null).ToDictionary(
技术分享                    k => k.Attribute("id").Value, 
技术分享                    v => 
技术分享                    {
技术分享                        string typeName = v.Attribute("type").Value;  
技术分享                        Type type = Type.GetType(typeName);  
技术分享                        return Activator.CreateInstance(type);
技术分享                    }
技术分享                );
技术分享
技术分享            //有参构造函数
技术分享            foreach (XElement item in objects.Where(obj => 
技术分享                obj.Element("constructor-arg") != null))
技术分享            {                                                                                                                                                  
技术分享                string id = item.Attribute("id").Value;
技术分享                string typeName = item.Attribute("type").Value;
技术分享                Type type = Type.GetType(typeName);
技术分享                var args = from property in type.GetConstructors()[0].GetParameters()
技术分享                           join el in item.Elements("constructor-arg")
技术分享                           on property.Name equals el.Attribute("name").Value
技术分享                           select Convert.ChangeType(el.Attribute("value").Value,
技术分享                           property.ParameterType);
技术分享                object obj = Activator.CreateInstance(type, args.ToArray());
技术分享                objectDefine.Add(id, obj);
技术分享            }
技术分享        }
技术分享
技术分享        /// <summary>
技术分享        /// 属性注入
技术分享        /// </summary>
技术分享        /// <param name="fileName"></param>
技术分享        private void DiObjects(string fileName)
技术分享        {
技术分享            XElement root = XElement.Load(fileName);
技术分享            var objects = from obj in root.Elements("object")
技术分享                          select obj;
技术分享
技术分享            foreach (KeyValuePair<string,object> item in objectDefine)
技术分享            {
技术分享                foreach (var el in objects.Where(e => 
技术分享                    e.Attribute("id").Value == item.Key).Elements("property"))
技术分享                {
技术分享                    Type type = item.Value.GetType();
技术分享                    //获取属性
技术分享                    foreach (PropertyInfo property in type.GetProperties())
技术分享                    {
技术分享                        if (property.Name == el.Attribute("name").Value)
技术分享                        {
技术分享                            if (el.Attribute("value") != null)
技术分享                            {
技术分享                                //设置属性值
技术分享                                property.SetValue(item.Value, 
技术分享                                    Convert.ChangeType(el.Attribute("value").Value, 
技术分享                                    property.PropertyType), null);
技术分享                            }
技术分享                            else if (el.Attribute("ref") != null)
技术分享                            {
技术分享                                object refObject = null;
技术分享
技术分享                                if (objectDefine.ContainsKey(el.Attribute("ref").Value))
技术分享                                {
技术分享                                    refObject = objectDefine[el.Attribute("ref").Value];
技术分享                                }
技术分享                                //设置关联对象属性
技术分享                                property.SetValue(item.Value, refObject, null);
技术分享                            }
技术分享                        }
技术分享                    }
技术分享                }
技术分享            }
技术分享        }
技术分享
技术分享        /// <summary>
技术分享        /// 获取对象
技术分享        /// </summary>
技术分享        /// <param name="id"></param>
技术分享        /// <returns></returns>
技术分享        public object GetObject(string id)
技术分享        {
技术分享            object result = null;
技术分享
技术分享            if (objectDefine.ContainsKey(id))
技术分享            {
技术分享                result = objectDefine[id];
技术分享            }
技术分享
技术分享            return result;
技术分享        }
技术分享    }
<?xml version="1.0" encoding="utf-8" ?>

<objects>

  <object id="person" type="SpringNetMyDi.Person, SpringNetMyDi">
    <!--属性值类型注入-->
    <property name="Name" value="Liu Dong"/>
    <property name="Age" value="27"/>

  </object>

  <object id="personDao" type="SpringNetMyDi.PersonDao, SpringNetMyDi">
    <!--构造器注入-->
    <constructor-arg name="intProp" value="1"/>

    <property name="Entity" ref="person" />
    
  </object>

</objects>
class Program
技术分享    {
技术分享        static void Main(string[] args)
技术分享        {
技术分享            ObjectFactory factory = ObjectFactory.Instance(@"F:\Exercise\SpringNet\Step1\SpringNet_Lesson9\SpringNetMyDi\Objects.xml");
技术分享
技术分享            PersonDao dao = (PersonDao)factory.GetObject("personDao");
技术分享
技术分享            Console.WriteLine("姓名:" + dao.Entity.Name);
技术分享            Console.WriteLine("年龄:" + dao.Entity.Age);
技术分享            Console.WriteLine(dao);
技术分享
技术分享            Console.ReadLine();
技术分享        }
技术分享    }

Spring.Net学习笔记十(打造简易的依赖注入框架)

标签:

原文地址:http://www.cnblogs.com/wangyhua/p/IOC10.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!