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

  我们在第三篇中学习里一个简易的IoC框架。今天我们接着上次的程序,实现带参数构造函数对象的实例和属性的注入 。
  我们知道可以通过反射获取类的构造函数及参数(GetConstructors方法);可以获取属性和属性的类型(GetProperties方法)。通过
Activator的CreateInstance(Type type, params object[] args)方法可以创建带参数构造函数的实例。通过SetValue方法可以给属性赋值,这样一来,我们就上次的代码稍加改造就可以实现属性的注入了。


  下面是完成的代码:

ContractedBlock.gifExpandedBlockStart.gifDomain
    public class Person
ExpandedBlockStart.gifContractedBlock.gif    
{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
public string Name getset; }
ExpandedSubBlockStart.gifContractedSubBlock.gif        
public int Age getset; }
    }


   
public class PersonDao
ExpandedBlockStart.gifContractedBlock.gif    
{
        
private int intProp;

        
public PersonDao(int intProp)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
this.intProp = intProp;
        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
public Person Entity getset; }

        
public override string ToString()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
return "构造函数参数intProp为:" + this.intProp;
        }

    }

 

ContractedBlock.gifExpandedBlockStart.gifObjectFactory
public class ObjectFactory
ExpandedBlockStart.gifContractedBlock.gif    
{
        
private IDictionary<stringobject> objectDefine = new Dictionary<stringobject>();

        
private ObjectFactory(string fileName)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            InstanceObjects(fileName);  
// 实例IoC容器
            DiObjects(fileName);  // 属性注入
        }


        
private static ObjectFactory instance;

        
private static object lockHelper = new object();

        
public static ObjectFactory Instance(string fileName)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (instance == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
lock (lockHelper)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    instance 
= instance ?? new ObjectFactory(fileName);
                }

            }

            
return instance;
        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 实例IoC容器
        
/// </summary>
        
/// <param name="fileName"></param>

        private void InstanceObjects(string fileName)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            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 
=> 
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        
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))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{                                                                                                                                                  
                
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);
            }

        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 属性注入
        
/// </summary>
        
/// <param name="fileName"></param>

        private void DiObjects(string fileName)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            XElement root 
= XElement.Load(fileName);
            var objects 
= from obj in root.Elements("object")
                          select obj;

            
foreach (KeyValuePair<string,object> item in objectDefine)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
foreach (var el in objects.Where(e => 
                    e.Attribute(
"id").Value == item.Key).Elements("property"))
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    Type type 
= item.Value.GetType();
                    
//获取属性
                    foreach (PropertyInfo property in type.GetProperties())
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        
if (property.Name == el.Attribute("name").Value)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
{
                            
if (el.Attribute("value"!= null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                            
{
                                
//设置属性值
                                property.SetValue(item.Value, 
                                    Convert.ChangeType(el.Attribute(
"value").Value, 
                                    property.PropertyType), 
null);
                            }

                            
else if (el.Attribute("ref"!= null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                            
{
                                
object refObject = null;

                                
if (objectDefine.ContainsKey(el.Attribute("ref").Value))
ExpandedSubBlockStart.gifContractedSubBlock.gif                                
{
                                    refObject 
= objectDefine[el.Attribute("ref").Value];
                                }

                                
//设置关联对象属性
                                property.SetValue(item.Value, refObject, null);
                            }

                        }

                    }

                }

            }

        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 获取对象
        
/// </summary>
        
/// <param name="id"></param>
        
/// <returns></returns>

        public object GetObject(string id)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
object result = null;

            
if (objectDefine.ContainsKey(id))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                result 
= objectDefine[id];
            }


            
return result;
        }

    }

 

ContractedBlock.gifExpandedBlockStart.gifApp.config
<?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>

 

ContractedBlock.gifExpandedBlockStart.gifProgram
   class Program
ExpandedBlockStart.gifContractedBlock.gif    
{
        
static void Main(string[] args)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            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/GoodHelper/archive/2009/11/02/SpringNet_MyDi.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/276336.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android 单元测试

首先AndroidManifest.xml View Code <?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android"http://schemas.android.com/apk/res/android"package"com.travelsky.test" android:versionCode"1"androi…

申万一级行业日指数_基金收评 | 指数震荡走弱,军工股成两市主线!后期行情如何?...

收评君复盘日记(2020年9月21日)三大指数集体收跌&#xff0c;北向资金全天大幅净流出近65亿元&#xff0c;军工板块表现强势。盘面回顾9月21日&#xff0c;两市全天高开低走&#xff0c;早盘指数弱势震荡&#xff0c;三大指数盘中一度翻红&#xff0c;但随后震荡走弱&#xff0…

若川的2016年度总结,毕业工作

可以点击上方的标签若川的故事、年度总结&#xff0c;查看往期文章有读者反馈说看我年度总结系列比我源码系列更有启发。所以打算把2016-2018的年度总结发布到公众号声明原创&#xff0c;希望对大家有所启发。&#xff08;虽然我的每一年都过得非常普通...&#xff09;以下是正…

jQuery之Ajax

转载链接&#xff1a;http://cargoj.iteye.com/blog/1008047 1 . jQuery帮助之Ajax请求&#xff08;一&#xff09;jQuery.ajax(options) 2 . jQuery帮助之Ajax请求&#xff08;二&#xff09;jQuery.get(url,[data],[callback] 3 . jQuery帮助之Ajax请求&#xff08;三&am…

面试官问:能否模拟实现JS的new操作符(高频考点)

可以点击上方的话题JS基础系列&#xff0c;查看往期文章这篇文章写于2018年11月05日&#xff0c;new模拟实现&#xff0c;Object.create是面试高频考点&#xff0c;之前发布在掘金有近2万人阅读&#xff0c;现在发布到公众号声明原创。1. 前言这是面试官问系列的第一篇&#xf…

跟我一起学WCF(2)——利用.NET Remoting技术开发分布式应用

一、引言 上一篇博文分享了消息队列&#xff08;MSMQ&#xff09;技术来实现分布式应用&#xff0c;在这篇博文继续分享下.NET平台下另一种分布式技术——.NET Remoting。 二、.NET Remoting 介绍 2.1 .NET Remoting简介 .NET REmoting与MSMQ不同&#xff0c;它不支持离线可得&…

二叉树的建立与遍历_51、二叉树遍历-重建二叉树JZ4

题目描述输入某二叉树的前序遍历和中序遍历的结果&#xff0c;请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}&#xff0c;则重建二叉树并返回。思路回顾三种经典的遍历&…

推荐关注这7个高质量的前端公众号

拓宽眼界&#xff0c;增加深度&#xff0c;在阅读的世界里&#xff0c;我们往往能找到不一样的态度&#xff0c;提升朋友圈质量&#xff0c;从关注这几个公众号开始。轻扫一下二维码就行了&#xff0c;你可以试试&#xff0c;肯定会有意外收获。大迁世界 简介&#xff1a;前端小…

Windows Live Writer 在win2003 的安装方法

下载Windows Live Writer整体安装包&#xff0c;最好是离线安装包 2.在xp系统上安装 3.查找C:\Program Files\Common Files\Windows Live\.cache目录 .cache目录是隐藏的&#xff0c;目录下面就是各个安装文件的msi安装包 4.拷贝相应的msi文件&#xff0c;到Windows 2003安装就…

decode 大于比较 小于_6 燃气输配系统6.3 压力不大于1.6Mpa的室外燃气管道城镇燃气设计规范 GB500282006(2020修订版)...

6.3 压力不大于1.6Mpa的室外燃气管道6.3.1中压和低压燃气管道宜采用聚乙烯管、机械接口球墨铸铁管、钢管或钢骨架聚乙烯塑料复合管&#xff0c;并应符合下列要求&#xff1a; 1 聚乙烯燃气管应符合现行的国家标准《燃气用埋地聚乙烯管材》GB15558.1 和《燃气用埋地聚乙烯管件…

若川的2017年度总结,一如既往

可以点击上方的标签若川的故事、年度总结&#xff0c;查看往期文章有读者反馈说看我年度总结系列比我源码系列更有启发。所以打算把2016-2018的年度总结发布到公众号声明原创&#xff0c;希望对大家有所启发。&#xff08;虽然我的每一年都过得非常普通...&#xff09;若川的20…

沟通:用故事产生共鸣

《沟通:用故事产生共鸣》(全彩) 基本信息作者&#xff1a; Nancy Duarte(南希.杜瓦特)译者&#xff1a; 冯海洋出版社&#xff1a;电子工业出版社ISBN&#xff1a;9787121195914上架时间&#xff1a;2013-4-1出版日期&#xff1a;2013 年3月开本&#xff1a;12开页码&#xff1…

若川的2018年度总结,平淡无奇

可以点击上方的标签若川的故事、年度总结&#xff0c;查看往期文章偷偷告诉你&#xff0c;公众号内回复【报告】&#xff0c;可以获取你自己的github 2020 年度报告昨晚在我的6个微信群里都发了红包&#xff0c;以这样的方式跨过了2020年。运营公众号真的挺难的&#xff0c;比如…

基于dnn的车牌识别_自然场景中文文字识别,身份证火车票都能识别

图像处理中OCR(Optical Character Recognition光学字符识别)场景非常多&#xff0c;也给大家的工作生活带来了很多便利&#xff0c;比如车牌识别就能管理停车场车辆的出入&#xff0c;快递时只需给一个带有快递信息的图就能自动解析上传发件信息和收件信息&#xff0c;再比如我…

年末的大厂前端面试总结(20届双非二本)-终入字节

关注若川视野, 回复"pdf" 领取资料&#xff0c;回复"1"&#xff0c;可加群长期交流学习自我介绍双非二本,软件工程,自学前端,今年毕业。喜欢编程,古风,日语和英语。常以冷月心之名混迹前端江湖,也曾在混迹网文圈时用冷月心做笔名签约掌阅,作品《清起风云》…

动图演示23个鲜为人知的VSCode快捷键

原文地址&#xff1a;https://dev.to/devmount/23-lesser-known-vs-code-shortcuts-as-gif-80尽管我在VS Code中经常使用许多快捷方式&#xff0c;以下快捷方式可能会派上用场&#xff0c;但我经常忘记它们的存在。我制作了一些GIF&#xff0c;以便更好地记住它们。也许这里面也…

使用C语言进行面向对象的开发--GObject入门[5]

转载请注明出处 blog.csdn.net/pingf0 或www.cnblogs.com/pingf 接上文这一部分简要介绍下类的析构&#xff0c;或者成为终结。还是多说几句&#xff0c;也算是对前文的补充1.生成一个类是由父到子&#xff0c;析构的时候自然与之相对是由子到父。2.GObject的内存管理并没有采用…

面试官问:能否模拟实现JS的bind方法(高频考点)

可以点击上方的话题JS基础系列&#xff0c;查看往期文章写于2018年11月21日&#xff0c;发布在掘金阅读量1.3w前言这是面试官问系列的第二篇&#xff0c;旨在帮助读者提升JS基础知识&#xff0c;包含new、call、apply、this、继承相关知识。面试官问系列文章如下&#xff1a;感…

连续投影算法_中航国画荣获“2020 IAV国际视听嘉年华” 大屏幕投影显示行业三大奖项!...

近日&#xff0c;“2020IAV国际视听嘉年华”在深圳湾创新生态园隆重举行&#xff0c;航空工业上电下属子公司中航国画作为2020年迪拜世博会中国馆官方合作伙伴应邀参加此次高峰论坛&#xff0c;并在展会期间凭借4K系列双色激光工程投影机、LP160UL系列超高亮度双色激光工程投影…