之前我们学习里一个简易的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();
        }
    }

转载于:https://www.cnblogs.com/wangyhua/p/IOC10.html

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

  1. Spring.NET学习笔记9——打造简易的依赖注入框架(练习篇) Level 100

    我们在第三篇中学习里一个简易的IoC框架.今天我们接着上次的程序,实现带参数构造函数对象的实例和属性的注入 . 我们知道可以通过反射获取类的构造函数及参数(GetConstructors方法):可以获 ...

  2. Spring.NET学习笔记——目录(原)

    目录 前言 Spring.NET学习笔记--前言 第一阶段:控制反转与依赖注入IoC&DI Spring.NET学习笔记1--控制反转(基础篇) Level 200 Spring.NET学习笔 ...

  3. Spring Cloud学习笔记【十二】Hystrix的使用和了解

    Spring Cloud学习笔记[十二]Hystrix的使用和了解 Hystrix [hɪst'rɪks],中文含义是豪猪,因其背上长满棘刺,从而拥有了自我保护的能力.本文所说的Hystrix是Net ...

  4. Spring.NET学习笔记10——方法的注入(基础篇) Level 200

    多数用户都会将容器中的大部分对象布署为singleton模式.当一个singleton对象需要和另一个singleton对象协作,或者一个非singleton对象需要和另一个非singleson对象协 ...

  5. Spring MVC 学习笔记 对locale和theme的支持

    Spring MVC 学习笔记 对locale和theme的支持 Locale Spring MVC缺省使用AcceptHeaderLocaleResolver来根据request header中的 ...

  6. Spring Cloud 学习笔记(四)-Spring Cloud Hystrix

    Spring Cloud 学习笔记(四)-Spring Cloud Hystrix 由于前一阵子项目的原因,今天才继续弄上,今天想学习一下Hystrix组件 这个组件还挺抽象的,最开始我一直没太明白, ...

  7. Spring Boot学习笔记-实践建言

    2019独角兽企业重金招聘Python工程师标准>>> 本文延续<Spring Boot学习笔记-快速示例>,从开发指南中摘出一些实践经验可供参考.这也是笔者看到的眼前一 ...

  8. Spring.NET学习笔记——前言

    Spring.NET是一个应用程序框架,其目的是协助开发人员创建企业级的.NET应用程序.它提供了很多方面的功能,比如依赖注入.面向方面编程(AOP).数据访问抽象及ASP.NET扩展等等.Sprin ...

  9. Spring Boot学习笔记-进阶(3)

    文章目录 Spring Boot学习笔记-进阶(3) 一.Spring Boot与缓存 二.Spring Boot与消息 三.Spring Boot与检索 四.Spring Boot与任务 异步任务 ...

  10. Spring Boot学习笔记-基础(2)

    Spring Boot学习笔记-基础(2) Spring Boot 优点: – 快速创建独立运行的Spring项目以及与主流框架集成 – 使用嵌入式的Servlet容器,应用无需打成WAR包 – st ...

最新文章

  1. python名片管理系统视频_python视频学习笔记6(名片管理系统开发)
  2. [html] HTML5中新添加的表单属性有哪些?
  3. php 转发邮件,PHP Email();我不接收转发的电子邮件
  4. 搜索引擎登录工具_“搜索引擎营销”有多重要!你知道吗?
  5. 九龙擒庄指标源码破译_擒庄系列:庄家难逃该指标,散户屡试不爽的秘籍!(附公式)...
  6. 步长条件梯度下降算法步长和收敛条件的设置的一些看法
  7. 隐藏TreeView中SiteMap的根节点
  8. 华为DHCP故障常用排查命令
  9. 计算机怎么格式化电脑吗,怎么格式化电脑
  10. web开发视频教程,CSS颜色基本样式
  11. 显示12306服务器处理中正在排队,12306排队等待中怎么办 12306一直在排队解决方法(图文)...
  12. 我和 flow.ci 的第一次亲密接触
  13. 掌握这9个单行代码技巧!你也能写出『高端』Python代码 ⛵
  14. 七牛云存储详细配置步骤
  15. 新时代程序员主流开发工具一览
  16. android 对数标度 图库,如何排序水平堆积条形图JS(具有对数标度)
  17. 在成都Java培训班学习五个多月有用吗?
  18. Linux下软中断过程(详细)源码总结
  19. 软件管理的“七个女妖”-不要相信她们
  20. h3c交换机模拟器怎么用_由浅入深学习网络设备模拟器HCL 第二篇 交换机的基本配置...

热门文章

  1. 【Android】proguard混淆代码
  2. 《代码大全2》读书笔记 Week9
  3. 第一次面试且失败的经历
  4. 【Jmeter自学】Linux环境下Jmeter运行
  5. getchar()不停止原因
  6. 大数据 数据平台方案评估
  7. MDI/MDIX接口
  8. linux平台 oracle 数据库 安装文档
  9. mongodb 笔记
  10. SQL知识点脑图(一张图总结SQL)