1 /// <summary> 2 /// 名称:Reflection/反射 3 /// 场景:有一个dll,通过反射我们来获取信息,并使用 4 /// </summary>
1 /// <summary> 2 /// 反射使用 3 /// 前提条件: 4 /// ①我们有一个 dll: language .dll 5 /// ②language.dll 里面有个 China.cs 类,类里面有个方法SayHi(); 6 /// 目的:获取china.cs,调用SayHi(); 7 /// </summary> 8 public static void GetClassInfo() 9 { 10 //第一步:using System.Reflection; 11 12 //第二步 使用关键字 Assembly 获取dll信息,有三种方法,一般我们使用第一种 13 Assembly assembly = Assembly.Load("language"); //dll的名称,不加.dll后缀名,这里的意思就是在当前运行文件夹下获取 dll 14 Assembly assembly2 = Assembly.LoadFile("D:/Refrition/bin/Debug/language.dll"); //dll所在的实际路径 15 Assembly assembly3 = Assembly.LoadFrom("language.dll"); //dll的全名称 16 17 //获取assembly里面的所有模块信息 18 foreach (var item in assembly.GetModules()) 19 { 20 Console.WriteLine(item.Name); 21 } 22 23 // 获取assembly里面的所有类型信息 24 foreach (var item in assembly.GetTypes()) 25 { 26 Console.WriteLine(item.Name); 27 } 28 29 Type type = assembly.GetType("language.China"); //(命名空间+类型名称) | 通过名称获取类型 30 object oValue = Activator.CreateInstance(type); //通过类型来创建该类型的实例 31 MethodInfo method = type.GetMethod("SayHi"); //通过方法的名称得到方法 32 method.Invoke(oValue,null); //调用方法(创建的实例,方法的参数) 33 }
反射 + 简单工厂+ 可配置/可扩展
前提条件:建一个类库,我们定义一个接口
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace DataBaseCrud 8 { 9 public interface IBaseCrudServer 10 { 11 void SayHi(); 12 } 13 }
新建一个类库 SqlServer.Server,然后在里面建一个类 sqlServerHelper.cs 然后引用 DataBaseCrudServer 命名空间
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using DataBaseCrud; 7 8 namespace SqlServer.Server 9 { 10 public class SqlServerHelper : IBaseCrudServer 11 { 12 public void SayHi() 13 { 14 Console.WriteLine("Sql server say hi"); 15 } 16 } 17 }
新建一个控制台应用程序,添加引用-》程序集-》System.Configuration,然后新建一个类:ReflexFactory.cs
这里是将我们知道的信息转到了配置文件里面,同上面一样
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Reflection; 7 using System.Configuration; 8 using DataBaseCrud; 9 10 namespace Reflex 11 { 12 /// <summary> 13 /// 14 /// </summary> 15 public static class ReflexFactory 16 { 17 private static string[] strConfig = ConfigurationManager.AppSettings["IDBConfig"].Split(','); //从App.config获取配置文件信息 18 19 private static string strTypeName = strConfig[1];//类型名称 20 21 private static string strDllName = strConfig[0];//dll名称 22 public static IBaseCrudServer CreateInstance() 23 { 24 Assembly assembly = Assembly.Load(strDllName); 25 Type type = assembly.GetType(strTypeName); 26 object oValue = Activator.CreateInstance(type); 27 return oValue as IBaseCrudServer; 28 } 29 } 30 }
App.config
1 <?xml version="1.0" encoding="utf-8" ?> 2 <configuration> 3 <startup> 4 <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" /> 5 </startup> 6 <appSettings> 7 <add key="IDBConfig" value="SqlServer.Server,SqlServer.Server.SqlServerHelper"/> 8 </appSettings> 9 </configuration>
主程序这里调用
1 using DataBaseCrud; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 8 namespace Reflex 9 { 10 class Program 11 { 12 static void Main(string[] args) 13 { 14 ReflexFactory.GetInfo(); 15 ReflexFactory.CreateInstance().SayHi(); 16 //ReflexFactory.CreateInstance2(); 17 //Singleton.CreateInstance(); 18 //ReflexFactory.CreateInstance3(); 19 //ReflexFactory.CreateInstance4(); 20 //ReflexFactory.CreateInstance5(); 21 Console.ReadKey(); 22 } 23 } 24 }
创建调用DLL里面的泛型/多构造函数等
1 /// <summary> 2 /// Reflection 调用DLL里面的普通类里面的普通类的多个构造函数 3 /// </summary> 4 public static void CreateInstance2() 5 { 6 Assembly assembly = Assembly.LoadFrom("DataBaseCrud.dll"); 7 Type type = assembly.GetType("DataBaseCrud.TestClass"); 8 9 object oValue = Activator.CreateInstance(type, null); 10 object oValue2 = Activator.CreateInstance(type, new object[] { 123 }); 11 object oValue3 = Activator.CreateInstance(type, new object[] { 123, "News" }); 12 } 13 /// <summary> 14 /// Reflection 调用DLL里面的单列 15 /// </summary> 16 public static void CreateInstance3() 17 { 18 Assembly assembly = Assembly.Load("DataBaseCrud"); 19 Type type = assembly.GetType("DataBaseCrud.Singleton"); 20 object oValue = Activator.CreateInstance(type, true); 21 } 22 23 /// <summary> 24 /// Reflection 调用DLL里面的泛型类并创建泛型类的实例 25 /// </summary> 26 public static void CreateInstance4() 27 { 28 Assembly assembly = Assembly.Load("DataBaseCrud"); 29 Type type = assembly.GetType("DataBaseCrud.GenericTest`3"); 30 Type typeNew = type.MakeGenericType(typeof(int), typeof(string), typeof(int)); 31 object oValue = Activator.CreateInstance(typeNew, new object[] { 123, "564", 654 }); 32 } 33 34 /// <summary> 35 /// Reflection 调用DLL里面的普通类里面的泛型方法 36 /// </summary> 37 public static void CreateInstance5() 38 { 39 Assembly assembly = Assembly.Load("DataBaseCrud"); 40 Type type = assembly.GetType("DataBaseCrud.GenericTest2"); 41 object oValue = Activator.CreateInstance(type); 42 MethodInfo methodInfo = type.GetMethod("Show"); 43 MethodInfo methodInfoNew = methodInfo.MakeGenericMethod(typeof(int), typeof(string), typeof(int)); 44 methodInfoNew.Invoke(oValue, new object[] { 123, "564", 654 }); 45 }
以上就是我对反射的理解和学习,如有疑问加QQ:443069755
欢迎来指教和讨论
2018年3月26日 补充说明
1 /// <summary> 2 /// Reflection 调用DLL里面的普通类里面的泛型方法 3 /// 扩展:使用 dynamic 弱类型来进行简写我们的反射 4 /// dynamic 运行时才会程序检查,注意使用,有性能损耗(会转成字典的情况,然后遍历检查) 5 /// </summary> 6 public static void CreateInstance5() 7 { 8 //常规的反射 9 { 10 Assembly assembly = Assembly.Load("DataBaseCrud"); 11 Type type = assembly.GetType("DataBaseCrud.GenericTest2"); 12 object oValue = Activator.CreateInstance(type); 13 MethodInfo methodInfo = type.GetMethod("Show"); 14 MethodInfo methodInfoNew = methodInfo.MakeGenericMethod(typeof(int), typeof(string), typeof(int)); 15 methodInfoNew.Invoke(oValue, new object[] { 123, "564", 654 }); 16 } 17 //使用 dynamic 来放便我们简写 18 { 19 Assembly assembly = Assembly.Load("DataBaseCrud"); 20 Type type = assembly.GetType("DataBaseCrud.GenericTest2"); 21 dynamic _dynamic = Activator.CreateInstance(type); 22 _dynamic.Show(123, "567", 654); 23 } 24 25 }