//1.动态读取Dll Assembly assembly = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory +@"EVEDAS.UPDLL.dll"); //2.获取某一个具体的类型:参数需要是类的全名称; Type type = assembly.GetType("EVEDAS.UPDLL.Api.A300"); //3.创建对象 object? oInstance = Activator.CreateInstance(type); //调用无参构造函数 object? oInstance1 = Activator.CreateInstance(type, new object[] {123,"ABC"}); //调用有参构造函数,参数按照顺序放在object数组中 //4.类型转换 var MesApi = oInstance as MesApi; // 5.调用方法 MesApi.SetValues();动态读取Dll–三种方式
1.LoadFrom:dll全名称,需要后缀
2.LoadFile:全路径,需要dll后缀,
3.Load dll:名称 不需要后缀
反射调用静态方法Assembly assembly = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory +@"EVEDAS.UPDLL.dll"); public ApiResult UserLogin(JObject SendData) { //全部参数组成数组 object[] args = new object[] { "A301", SendData }; Type type1 = assembly.GetType("EVEDAS.UPDLL.Api.A300"); return (ApiResult)type1.InvokeMember("Execute", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, null, args); }使用dynamic 作为类型的声明,在调用的时候,没有限制
dynamic dInstance = Activator.CreateInstance(type); dInstance.SetValues();
dynamic 是动态类型,它不在编译时决定类型而是运行时决定是什么类型,会避开编译器的检查;
通过反射破坏单例反射动态记载dll,元数据中只要有的不论是私有或共有,都可以给找出来。不用关注权限问题,反之私有化成员只能从内部访问。
反射调用方法(直接调用不做类型转换)步骤1.获取方法MethodInfo
步骤2.执行MethodInfo 的Invoke方法,传递方法所在的类的实例对象+参数
Assembly assembly = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory +@"EVEDAS.UPDLL.dll"); Type type = assembly.GetType("EVEDAS.UPDLL.Api.A300"); object oInstance = Activator.CreateInstance(type); MethodInfo show = type.GetMethod("ShowTest"); show.Invoke(oInstance, new object[] { }); //无参数方式一 show.Invoke(oInstance, new object[0]);//无参数方式二 show.Invoke(oInstance, null);//无参数方式三调用有参数的方法(重载方法)
需要通过方法参数类型类区别方法,传递参数需要匹配参数类型
Assembly assembly = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory +@"EVEDAS.UPDLL.dll"); Type type = assembly.GetType("EVEDAS.UPDLL.Api.A300"); object oInstance = Activator.CreateInstance(type); MethodInfo show2 = type.GetMethod("ShowTest"); show2.Invoke(oInstance, new object[] { 123 }); MethodInfo show3 = type.GetMethod("ShowTest", new Type[] { typeof(string), typeof(int) }); show3.Invoke(oInstance, new object[] { "测试输入", 234 });调用私有方法
在获取方法的时候,加上参数BindingFlags.NonPublic | BindingFlags.Instance
Assembly assembly = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory +@"EVEDAS.UPDLL.dll"); Type type = assembly.GetType("EVEDAS.UPDLL.Api.A300"); object oInstance = Activator.CreateInstance(type); MethodInfo show4 = type.GetMethod("ShowTest",BindingFlags.NonPublic | BindingFlags.Instance); show4.Invoke(oInstance, new object[] { 123 });调用泛型方法
获取到方法后,先确定类型,严格按照参数类型传递参数就可以正常调用 。 泛型是延迟声明,调用的时候,才确定类型。
//1.调用泛型方法 Assembly assembly = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory +@"EVEDAS.UPDLL.dll"); Type type = assembly.GetType("EVEDAS.UPDLL.Api.A300"); object oInstance = Activator.CreateInstance(type); MethodInfo show = type.GetMethod("Show"); //泛型方法,先设置泛型方法的类型 MethodInfo genericshow = show.MakeGenericMethod(new Type[] { typeof(int), typeof(string), typeof(DateTime) }); genericshow.Invoke(oInstance, new object[] { 123, "测试", DateTime.Now }); //2.调用泛型类 Assembly assembly = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory +@"EVEDAS.UPDLL.dll"); Type type = assembly.GetType("EVEDAS.UPDLL.Api.A300"); Type generType = type.MakeGenericType(new Type[] { typeof(int) }); object oInstance = Activator.CreateInstance(generType); //泛型类,设置泛型类的类型 MethodInfo show = generType.GetMethod("Show"); //泛型方法,先设置泛型方法的类型 MethodInfo genericMethod = show.MakeGenericMethod(new Type[] { typeof(string), typeof(DateTime) }); genericMethod.Invoke(oInstance, new object[] { 123, "测试", DateTime.Now });反射调用字段属性
Assembly assembly = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory +@"EVEDAS.UPDLL.dll"); Type type = assembly.GetType("EVEDAS.UPDLL.Api.A300"); object oInstance = Activator.CreateInstance(type); foreach (var prop in type.GetProperties()) { if (prop.Name.Equals("Id")) { //设置属性 prop.SetValue(oInstance, 134); } else if (prop.Name.Equals("Name")) { //获取属性 prop.GetValue(oInstance); } }