浅谈.Net反射
一.何为反射?
reflection; 程序集包含模块,而模块包含类型,类型又包含成员。反射则提供了封装程序集、模块和类型的对象。我们可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,就可以调用类型的方法或访问其字段和属性。
二.那些反射用到的类
1)反射核心类:System.Type类
2)System.Reflection.Assembly类
<span style="font-family:FangSong_GB2312;"> //Assembly通过此类可以加载操纵一个程序集,并获取程序集内部信息 Assembly assembly = Assembly.Load("MyAssembly"); //引用命名空间 Assembly assembly2 = Assembly.LoadFrom("D:\testDll.dll"); Assembly dll = Assembly.LoadFile(Environment.CurrentDirectory + "\\testDll.dll"); //通过dll文件去反射其中所有的类型,但不会加载引用的程序集</span>
三.如何使用反射?
1)要引用的程序集和需要程序集的程序在同一目录时,不需要加载程序集,直接可以获取其中的类型.举例:
<span style="font-family:FangSong_GB2312;font-size:18px;"> Type math = Type.GetType("testDll.Math", true); //获取类型 MethodInfo method = math.GetMethod("add"); //获取testdll.math中的方法add int count = (int)method.Invoke(null, new object[] { 10, 20 }); //给add方法传参数并去调用方法add Console.WriteLine("Invoke Method:" + count.ToString()); Console.ReadLine();</span>
2)要引用的程序集合需要程序集不在同一目录中时,先要加载程序集,才能获取其中的类和类的方法等。举例:
<span style="font-family:FangSong_GB2312;"> Assembly dll = Assembly.LoadFile(Environment.CurrentDirectory + "\\testDll.dll"); //通过dll文件去反射其中所有的类型,但不会加载引用的程序集 //Environment.CurrentDirectory 属性:获取或设置当前工作目录的完全限定路径 Type math = dll.GetType("testDll.Math", true); //获取类型 MethodInfo method = math.GetMethod("add"); //获取testdll.math中的方法add int count = (int)method.Invoke(null, new object[] { 10, 20 }); //给add方法传参数并去调用方法add Console.WriteLine("Invoke Method:" + count.ToString()); Console.ReadLine();</span>
3)反射+配置文件
看过大话设计模式的,都知道在抽象工厂模式中.小菜在大鸟的指点下,用简单工厂,再用反射,再用配置文件,一步步将抽象工厂改装, 使得抽象工厂的缺点和个各类之间的耦合性都大大降低. 在不用反射+配置文件时,抽象工厂的问题是:
*如果需要增加多个数据库,就要增加多个类,更麻烦。
在使用反射+配置文件后,抽象工厂的改变是:
*如果需要更换数据库,不需改变代码,只需要修改配置文件中DB的值。
小结:反射技术的使用去除了switch或if,解除分支判断的耦合。在这里,反射可以说是简化了工厂的实现。
4)项目实践
<span style="font-family:FangSong_GB2312;"> //EF:就是让EF上下文保存了一下。不适合于集群(后期使用key,value保存在分布式缓存中,key为guid) public int SaveChanges() { //return DbContextFactory.GetCurrentDbContext().SaveChanges(); string strAssembly = ConfigurationManager.AppSettings["DalAssembly"]; string strDbContextFactoryclassFulleName = ConfigurationManager.AppSettings["DbContextFactoryclassFulleName"]; Assembly assembly = Assembly.Load(strAssembly); Type type = assembly.GetType(strDbContextFactoryclassFulleName); MethodInfo methodInfo = type.GetMethod("GetCurrentDbContext"); return ((DbContext)methodInfo.Invoke(null, null)).SaveChanges(); }</span>
四.为什么要用反射?
反射与引用
相比较下,引用执行效率高,但是当你引用的dll文件很多的时候,一遍遍的引用dll...,那就不是什么好事了。 反射呢,虽执行效率低,但在上述情况出现时,它只需动态反射一次dll文件,不用去管dll文件时新增还是减少的情况了,有点一劳永逸的味道。
在真正用的过程中,反射回合委托,泛型,特性等等结合使用,这都是需要进一步研究学习的地方
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。