在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
原文:https://blog.csdn.net/pengdayong77/article/details/47622235
在.Net 中,程序集(Assembly)中保存了元数据(MetaData)信息,因此就可以通过分析元数据来获取程序集中的内容,比如类,方法,属性等,这大大方便了在运行时去动态创建实例。
反射提供了封装程序集、模块和类型的对象(Type 类型)。可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性。如果代码中使用了属性,可以利用反射对它们进行访问。 主要用途:
今天我就介绍下后面的两个用途,其实最初的目的只是想根据配置文件中的值创建对应对象。 Dll 先上一段代码,这是要调用的ClassGreenerycn类,它被编译为DllDemo.dll。
using System; namespace DllDemo { public class ClassGreenerycn { public string Name { get; set; } public bool IsTest { get; set; } public void Hello() { Console.WriteLine(Name); } } }
很简单的代码,就是一个类中有两个属性,Hello方法会向命令行中输出Name的名称。
使用反射创建Dll中的类实例并调用方法现在再新建一个命令行的工程,该工程就一个用途,动态加载DllDemo.dll,然后实例化一个Name为Greenerycn,IsTest为True的对象,并调用Hello方法。 详细步骤如下: 1.引用反射的命名空间: using System.Reflection; 2.动态加载Dll 动态加载Dll有3个函数: public static Assembly Load(string assemblyString);
public static Assembly LoadFile(string path);
public static Assembly LoadFrom(string assemblyFile);
3.获取ClassGreenerycn类的类型 var type = asm.GetType("DllDemo.ClassGreenerycn"); 注意,这里需要完整的类型名称,包括签名的命名空间。 4.创建该类型的实例 var instance = asm.CreateInstance("DllDemo.ClassGreenerycn"); 5.设置属性 type.GetProperty("Name").SetValue(instance, "http://greenerycn.cnblogs.com", null); type.GetProperty("IsTest").SetValue(instance, true, null); 6.获取Hello方法 var method = type.GetMethod("Hello"); 7.调用Hello方法 method.Invoke(instance, null); 8.编译运行 完整的代码
//在外部动态库和本地类继承同一抽象类AbstractHi并实现同一接口interface 的情况下(甚至接口引用相同实体),主要用于加载不同类名,但实际签名相同的方法的类 //实体 public class Person { public string Name {get ;set} } //1.创建接口 public interface IHi { string SayHi(); Person GetPerson(); } //2.抽象类继承接口 public abstract class AbstractHi : IHi { public abstract string SayHi(); public abstract Person GetPerson(); } ----------------------------------------------- //3.动态库实现(dll文件) public class DllDemo : AbstractHi { public override string SayHi() { return "Hi"; } public override Person GetPerson() { var person =new Person (); Person.Name = "MyName"; return person ; } } ------------------------------------------------ //4.加载动态库 /// <summary> /// 返回操作对象,加载类名包含defaultClass字符串的类 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="defaultClass"></param> /// <returns></returns> public static T GetDllDemo<T>(string defaultClass) where T : class { try { var asm = Assembly.LoadFile(@"d:\3_code\DotNet\DllDemo\DllDemo\bin\Debug\DllDemo.dll"); var dllDemo = (from d in asm.DefinedTypes where d.BaseType.FullName.Contains(defaultClass) select d.FullName ).FirstOrDefault(); var type = asm.GetType(dllDemo); return Activator.CreateInstance(type) as T; } catch (Exception ex) { throw ex; } } //5.实例化 public class DllDemoBLL { private AbstractHi_DAL public DllDemoBLL() { _DAL = GetDllDemo<AbstractHi>("DllDemo"); } public string SayHi2() { return _DAL. SayHi(); } public Person GetPerson2() { return _DAL. GetPerson(); } } //6.调用 private DllDemoBLL _BLL = new DllDemoBLL(); public string SayHi3() { return _BLL.SayHi2(); //最终返回 "Hi" } public Person GetPerson3() { return _BLL.GetPerson2(); //最终返回 Person 属性Name=“MyName” 的实体 }
|
请发表评论