1. 反射的原理
反射是由框架提供的一个类库,可以访问dll中的metadata,动态获取dll的信息,并使用它。
2. 反射+简单工厂+可配置
反射三步曲: a. 动态加载dll
b. 获取类型信息
c. 创建对象
看代码:
先声明了一个接口DB.Interface 和一个类DB.MySql
namespace DB.Interface { public interface IDBHelper //定义一个连接数据库的接口 { void Query(); } }
namespace DB.MySql { public class MySqlHelper:IDBHelper { public MySqlHelper() { Console.WriteLine("{0}被构造", this.GetType().Name); } public void Query() { Console.WriteLine("{0}.Query", this.GetType().Name); } } }
配置文件中加<appSetting>字段
<?xml version="1.0" encoding="utf-8" ?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" /> </startup> <appSettings> <!--<add key="IDBHelperType" value="DB.SqlServer,DB.SqlServer.SqlSeverHelper"/>--> <add key="IDBHelperType" value="DB.MySql,DB.MySql.MySqlHelper"/> </appSettings> </configuration>
创建一个简单工厂
public class ObjectFactory //简单工厂,创建对象 { private static string IDBHelperType = ConfigurationManager.AppSettings["IDBHelperType"]; //用key来获取value字符串 private static string DllName = IDBHelperType.Split(',')[0]; private static string TypeName = IDBHelperType.Split(',')[1]; public static IDBHelper CreateInstance() { Assembly assembly = Assembly.Load(DllName);// 1. 动态加载dll,参数为dll的名称,没有后缀 Type type = assembly.GetType(TypeName);//2.获取类型信息,传递完整类型名称,namespace+classname object oObject = Activator.CreateInstance(type);//3.创建对象 return (IDBHelper)oObject; } }
主程序
{ Console.WriteLine("*********************reflection config************************"); IDBHelper Helper = ObjectFactory.CreateInstance(); Helper.Query(); }
3. 反射的有缺点:
优点: 动态
缺点: 代码麻烦;避开编译器的检查;耗性能
反射的性能可以优化,下面给了一段测试反射性能的代码,并给出结果。
{ Console.WriteLine("*********************Monitor************************"); long commonTime = 0; long reflectionTime = 0; { Stopwatch watch = new Stopwatch(); watch.Start(); for(int i=0;i<1000000;i++) { IDBHelper Helper = new SqlSeverHelper(); Helper.Query(); } watch.Stop(); commonTime = watch.ElapsedMilliseconds; } { Stopwatch watch = new Stopwatch(); watch.Start(); Assembly assembly = Assembly.Load("DB.SqlServer");// 1. 动态加载dll,参数为dll的名称,没有后缀 Type type = assembly.GetType("DB.SqlServer.SqlSeverHelper");//2.获取类型信息,传递完整类型名称,namespace+classname for (int i = 0; i < 1000000; i++) { object oObject = Activator.CreateInstance(type);//3.创建对象 ((IDBHelper)oObject).Query();//4.调用方法 } watch.Stop(); reflectionTime = watch.ElapsedMilliseconds; } Console.WriteLine("commonTime={0} reflectionTime={1}", commonTime, reflectionTime); }
运行结果