前段时间敲代码,需要动态的加载的外部DLL,并且解析DLL,来读取DLL中的类,属性,有时候还需要读取特性的值。这个问题刚开始遇到,是一点想法没有,以前没有这么用过,后来查资料,请教别人,终于有了结果。当有了代码之后,发现在找问题的过程中,我糊涂了,因为解决这个问题的方式主要是——反射。我是通过利用反射进行DLL的动态加载和调用。下面来看看我的实现吧。
我做的例子是通过读取DLL的路径来加载DLL,然后遍历的读取DLL的类名,遍历每个类的属性,和类以及属性的特性。
主要代码有这几个:
1、加载程序集:
Assembly.LoadFile 只加载指定文件,并不会自动加载依赖程序集.Assmbly.Load无需后辍名
2、利用类型的命名空间和名称获得类的类型
Type type=ass.GetType(“TypeName”);
3、利用指定的参数实例话类型
Object bj = Activator.CreateInstance(type,params[]);
4、通过方法名称获得方法
MethodInfo mi=type.GetMethod(“MehtodName”);
5、根据参数直线方法,返回值就是原方法的返回值
6、加载类里面的属性
PropertyInfo p = this.GetType().GetProperty("xxx");
实例如下:
<span style="font-family:KaiTi_GB2312;font-size:18px;"> /// <summary> /// 动态加载实体DLL /// </summary> /// <returns></returns> public ActionResult LoadEntityDll(string path) { <span style="font-family:KaiTi_GB2312;"> //根据路劲加载DLL </span> LoadDLL dld = new LoadDLL(path); ass = new LoadDLL(path).GetAssembly(); //DynamicLoadDLL.LoadDLL dld = new DynamicLoadDLL.LoadDLL(path); //获取DLL中包含的全部类型 foreach (var types in dld.GetTypes()) { //获得类的名称---特性 if (types.GetCustomAttributes(typeof(ClassesAttribute),false)!=null ) { string name = types.Name; ClassesAttribute className = (ClassesAttribute)types.GetCustomAttributes(typeof(ClassesAttribute), true).FirstOrDefault(); //实体___王永霞 A a=new A(); a.EntityName = name; if (className!= null) { a.EntityDesc = className.TableName; } else { a.EntityDesc = name; } //加载属性 string strnamespace = types.Namespace; DynamicLoadProperty(strnamespace, name, a); } } return View("xx"); } /// <summary> /// 读取实体属性--王勇霞 /// </summary> public void DynamicLoadProperty(string strnamespace, string classname, A a) { aWCF = UIServiceFactory.GetQueryPropertiesService(); LoadClass dlc = LoadClass.GetInstance(ass, strnamespace, classname); #region 获取全部属性-- 给实体赋值 foreach (var attrs in dlc.GetAttrs()) { //添加到数据库表中 a.ControlHtmlId = attrs.Name; //读取注解 //DisplayAttribute temDesc = (DisplayAttribute)attrs.GetCustomAttributes(typeof(DisplayAttribute), true).FirstOrDefault(); ColumAttribute temDesc = (ColumAttribute)attrs.GetCustomAttributes(typeof(ColumAttribute), true).FirstOrDefault(); if (temDesc != null) { a.PropertyDesc = temDesc.ColumName; } else { a.PropertyDesc = attrs.Name; } } #endregion } #endregion</span>
总结:以上是两个方法,一个是加载DLL的类,一个是读取类中的属性,其实大家仔细观察会发现。这段代码的的眼,及一句话我认为,就是反射的这句:
<span style="font-family:KaiTi_GB2312;font-size:18px;">ass = new LoadDLL(path).GetAssembly();</span>
剩下的加载类,加载方法,加载属性,加载特性,都是顺便的事情。但是在开始的时候,就是没有想到?为什么?
事后反思,一是代码经验不够,二是没有静下来好好思考这个问题。以前学习设计模式的时候就接触反射了,现在看来是没有理解反射的原理。反射本就是“读取类的一种方式,通过字符串来找到类”。这次又算是对反射的查漏补缺。最后把反射的概念分享给大家:http://www.csharpwin.com/csharpspace/8982r7645.shtml。