zoukankan      html  css  js  c++  java
  • Spring.Net学习笔记十(打造简易的依赖注入框架)

          之前我们学习里一个简易的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:ExerciseSpringNetStep1SpringNet_Lesson9SpringNetMyDiObjects.xml");

                PersonDao dao = (PersonDao)factory.GetObject("personDao");

                Console.WriteLine("姓名:" + dao.Entity.Name);
                Console.WriteLine("年龄:" + dao.Entity.Age);
                Console.WriteLine(dao);

                Console.ReadLine();
            }
        }
  • 相关阅读:
    Spring不再推荐使用字段注入
    谈谈Web安全色(web safe color)
    mybatis写mapper文件注意事项
    GitHub下载加速
    ssm项目 ajax发起post请求,控制台一直404
    第一篇随笔
    C语言编程练习64:还是畅通工程
    C语言编程练习63:完数
    C语言编程练习62:汉诺塔3
    C语言编程练习61:Tempter of the bone
  • 原文地址:https://www.cnblogs.com/wangyhua/p/IOC10.html
Copyright © 2011-2022 走看看