首页 > 代码库 > C#解析DLL————反射

C#解析DLL————反射

    前段时间敲代码,需要动态的加载的外部DLL,并且解析DLL,来读取DLL中的类,属性,有时候还需要读取特性的值。这个问题刚开始遇到,是一点想法没有,以前没有这么用过,后来查资料,请教别人,终于有了结果。当有了代码之后,发现在找问题的过程中,我糊涂了,因为解决这个问题的方式主要是——反射。我是通过利用反射进行DLL的动态加载和调用。下面来看看我的实现吧。


  我做的例子是通过读取DLL的路径来加载DLL,然后遍历的读取DLL的类名,遍历每个类的属性,和类以及属性的特性。

   主要代码有这几个:

   1、加载程序集:

        A ssembly ass=Assembly.LoadFrom(DllPath);

        Assembly.LoadFile 只加载指定文件,并不会自动加载依赖程序集.Assmbly.Load无需后辍名

   2、利用类型的命名空间和名称获得类的类型

       Type type=ass.GetType(“TypeName”);

   3、利用指定的参数实例话类型

       Object bj = Activator.CreateInstance(type,params[]);

    4、通过方法名称获得方法

       MethodInfo mi=type.GetMethod(“MehtodName”);

    5、根据参数直线方法,返回值就是原方法的返回值


        mi.Invoke(obj,params[]);

     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。

    

C#解析DLL————反射