文档章节

动态加载dll,扩展系统功能

白志华
 白志华
发布于 2015/10/18 10:54
字数 905
阅读 5
收藏 0
点赞 0
评论 0

动态加载dll,主要是为了扩展功能,增强灵活性而实现的。主要通过xml配置,来获取所有要动态加载的dll,然后通过反射机制来调用dll中的类及其方法。


研究了一天,小有所得,写了一个简单的动态加载dll的通用模块,拿出来与大家分享一下:


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace DynamicLoadDLL
{
    /// <summary>
    /// 动态加载dll
    /// </summary>
    public class LoadDLL
    {
        private Assembly ass = null;

        /// <summary>
        /// 加载dll
        /// </summary>
        /// <param name="dllPath">dll文件路径</param>
        public LoadDLL(string dllPath)
        {
            this.ass = Assembly.LoadFrom(dllPath);                     //利用dll的路径加载(fullname)
        }

        /// <summary>
        /// 返回反射的dll
        /// </summary>
        /// <returns></returns>
        public Assembly GetAssembly()
        {
            return this.ass;
        }

        /// <summary>
        /// 获取所有类名
        /// </summary>
        /// <returns></returns>
        public Type[] GetClass()
        {
            return ass.GetTypes();
        }

        /// <summary>
        /// 获取程序集下的所有文件名
        /// </summary>
        /// <returns></returns>
        public Module[] GetModules()
        {
            return ass.GetModules();            
        }

        /// <summary>
        /// 获取程序集清单文件表中的文件
        /// </summary>
        /// <returns></returns>
        public FileStream[] GetFiles()
        {
            return ass.GetFiles();
        }

    }
}

这个是加载dll的,然后返回一个Assembly类型的一个反射值,如果该dll中有多个命名空间和类的话,就只用一个 Assembly类型的一个反射值即可以完成调用,否则每次生成一个类,都需要反射一次。IO操作相对而言是比较耗费CPU,影响效率的。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace DynamicLoadDLL
{
    /// <summary>
    /// 加载类
    /// </summary>
    public class LoadClass
    {
        private static LoadClass dlc = null;
        private Type type;
        private object obj = null;                                         //实例

        /// <summary>
        /// 加载dll
        /// </summary>
        /// <param name="ass">dll引用</param>
        /// <param name="nameSpace">类的命名空间</param>
        /// <param name="classPath">类名称</param>
        private LoadClass(Assembly ass, string nameSpace, string classPath)
        {
            //加载dll后,需要使用dll中某类.
            type = ass.GetType(nameSpace + "." + classPath);                                //利用类型的命名空间和名称获得类型

            //需要实例化类型,才可以使用,参数可以人为的指定,也可以无参数,静态实例可以省略
            obj = Activator.CreateInstance(type);                         //利用指定的参数实例话类型

        }

        /// <summary>
        /// 加载dll
        /// </summary>
        /// <param name="ass">dll引用</param>
        /// <param name="nameSpace">类的命名空间</param>
        /// <param name="classPath">类名称</param>
        public static LoadClass GetInstance(Assembly ass, string nameSpace, string classPath)
        {
            if (dlc == null)
            {
                dlc = new LoadClass(ass, nameSpace, classPath);
            }
            return dlc;
        }

        /// <summary>
        /// 获取属性集
        /// </summary>
        /// <returns>返回属性值</returns>
        public PropertyInfo[] GetAttrs()
        {
            //调用类型中的某个属性:
            PropertyInfo[] prop = type.GetProperties();                //通过属性名称获得属性

            //返回属性集
            return prop;
        }

        public MethodInfo[] GetMethods()
        {
            //调用类型中的方法:
            MethodInfo[] method = type.GetMethods(BindingFlags.NonPublic);                //获得方法集

            //返回方法集
            return method;
        }


        /// <summary>
        /// 获取属性值
        /// </summary>
        /// <param name="attrName">属性名称</param>
        /// <returns>返回属性值</returns>
        public object GetAttrValue(string attrName)
        {
            //调用类型中的某个属性:
            PropertyInfo prop = type.GetProperty(attrName);                //通过属性名称获得属性

            //返回属性值
            return prop.GetValue(obj);
        }

        /// <summary>
        /// 设置属性值
        /// </summary>
        /// <param name="attrName">属性名称</param>
        /// <returns>返回属性值</returns>
        public void SetAttrValue(string attrName, string attrValue)
        {
            //调用类型中的某个属性:
            PropertyInfo prop = type.GetProperty(attrName);                //通过属性名称获得属性

            //返回属性值
            prop.SetValue(obj, attrValue);
        }

        /// <summary>
        /// 执行类方法
        /// </summary>
        /// <param name="methodName">方法名称</param>
        /// <param name="paras">参数</param>
        /// <param name="types">参数类型</param>
        /// <returns></returns>
        public object GetMethod(string methodName, object[] paras,Type[] types)
        {
            
            //调用类型中的某个方法:
            MethodInfo method = type.GetMethod(methodName,types);                //通过方法名称获得方法

            //执行方法
            return method.Invoke(obj, paras);
        }
    }
}

上面这个类根据dll反射值,命名空间和类名,反射出一个具体的类,还提供了属性和方法的调用方法。很方便。


这些是我在研究插件编程时,顺带研究的,不太深入,但希望对你能有所帮助。


版权声明:本文为博主原创文章,未经博主允许不得转载。

本文转载自:http://blog.csdn.net/xiaoxian8023/article/details/8334027

共有 人打赏支持
白志华
粉丝 29
博文 265
码字总数 57524
作品 0
长沙
程序员
dll的概念 dll导出变量 函数 类 (转)

1、 DLL的概念 DLL(Dynamic Linkable Library),动态链接库,可以向程序提供一些函数、变量或类。这些可以直接拿来使用。 静态链接库与动态链接库的区别: (1)静态链接库与动态链接库都是共...

长平狐
2012/10/08
675
0
qt实现-给SQLITE添加自定义函数

需要使用sqlite里的password对某个字段进行加密,由于使用的sqlite是由QT封装好的QSqlDatabase,没有发现加载扩展函数的方法,所以自己实现了一个。 在网上也没找到相应的参考,就自己查官方文...

quanwei9958
2014/12/21
0
0
LoadRunner使用动态链接库技术

什么是动态库? 动态库一般又叫动态链接库英文为DLL,是Dynamic Link Library 的缩写形式,DLL是一个包含可由多个程序同时使用的代码和数据的库,DLL不是可执行文件。动态链接提供了一种方法...

长平狐
2013/03/12
60
0
Linux-静态链接库和动态链接库

博文说明【前言】: 本文将通过个人口吻介绍Linux中静态链接库和动态链接库相关知识,在目前时间点【2017年6月14号】下,所掌握的技术水平有限,可能会存在不少知识理解不够深入或全面,望大...

1清风揽月1
2017/06/14
0
0
2014百度校园招聘软件研发类笔试(深圳)

时间:2013年9月28日。 地点:深圳 职位:软件研发 问答题:(10*3) 1.动态链接库(DLL)与静态链接库(lib)的优缺点: 静态链接库和动态链接库都是共享代码的方式,如果采用静态链接库,则无...

SibylY
2013/09/28
0
0
Win32环境下动态链接库(DLL)编程原理

比较大应用程序都由很多模块组成,这些模块分别完成相对独立的功能,它们彼此协作来完成整个软件系统的工作。其中可能存在一些模块的功能较为通用,在构造其它软件系统时仍会被使用。在构造软...

晨曦之光
2012/03/09
0
0
VC++动态链接库(DLL)编程[精]

1.概论   先来阐述一下DLL(Dynamic Linkable Library)的概念,你可以简单的把DLL看成一种仓库,它提供给你一些可以直接拿来用的变量、函数或类。在仓库的发展史上经历了“无库-静态链接库...

barsoom
2012/12/07
0
1
为什么需要反射?

1)当你做一个软件可以安装插件的功能,你连插件的类型名称都不知道,你怎么实例化这个对象呢?因为程序是支持插件的(第三方的),在开发的时候并不知道 。所以,无法在代码中 New出来 ,但...

王大豆
2015/09/11
265
0
PHP运行模式

http://www.cnblogs.com/xia520pi/p/3914964.html 1、运行模式 关于PHP目前比较常见的五大运行模式: 1)CGI(通用网关接口 / Common Gateway Interface) 2)FastCGI(常驻型CGI / Long-Li...

xiao酒窝
2017/01/22
0
0
动态嵌入式DLL木马的发现与清除

随着MS的操作系统从Win98过渡到Winnt系统(包括2k/xp),MS的任务管理器也一下子脱胎换骨,变得火眼金睛起来(在WINNT下传统木马再也无法隐藏自己的进程),这使得以前在win98下靠将进程注册为系...

技术小阿哥
2017/11/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Weblogic问题解决记录

问题:点击登录,页面刷新但是不进去管理界面。解决:删除cookies再登录。

wffger
26分钟前
0
0
RxJava2的错误处理方案

最近使用retrofit2 + rxKotlin2写接口访问,想尽量平铺代码,于是就想到当借口返回的状态码为「不成功」时(比如:code != 200),就连同网络错误一起,统一在onError方法中处理。想法总是好的...

猴亮屏
33分钟前
0
0
程序的调试信息

调试二进制程序时,经常要借助GDB工具,跟踪程序的执行流程,获取程序执行时变量的值,以发现问题所在。GDB能得到这些信息,是因为编译程序时,编译器保存了相应的信息。Linux下的可执行程序...

qlee
56分钟前
0
0
应用级缓存

缓存命中率 从缓存中读取数据的次数与总读取次数的比例,命中率越高越好 java缓存类型 堆缓存 guavaCache Ehcache3.x 没有序列化和反序列化 堆外缓存ehcache3.x 磁盘缓存 存储在磁盘上 分布式...

writeademo
今天
0
0
python爬虫日志(3)find(),find_all()函数

1.一般来说,为了找到BeautifulSoup对象内任何第一个标签入口,使用find()方法。 以上代码是一个生态金字塔的简单展示,为了找到第一生产者,第一消费者或第二消费者,可以使用Beautiful Sou...

茫羽行
今天
0
0
java:thread:顺序执行多条线程

实现方案: 1.调用线程的join方法:阻塞主线程 2.线程池 package com.java.thread.test;public class MyThread01 implements Runnable {@Overridepublic void run() {Syste...

人觉非常君
今天
0
0
ElasticSearch 重写IK分词器源码设置mysql热词更新词库

常用热词词库的配置方式 1.采用IK 内置词库 优点:部署方便,不用额外指定其他词库位置 缺点:分词单一化,不能指定想分词的词条 2.IK 外置静态词库 优点:部署相对方便,可以通过编辑指定文...

键走偏锋
今天
19
0
Git 2.18版本发布:支持Git协议v2,提升性能

Git 2.18版本发布:支持Git协议v2,提升性能Git 2.18版本发布:支持Git协议v2,提升性能 新版本协议的主要驱动力是使 Git 服务端能够对各种 ref(分支与 tag)进行过滤操作。 这就意味着,G...

linux-tao
今天
0
0
python浏览器自动化测试库【2018/7/22-更新】

64位py2.7版本 更新 document_GetResources 枚举页面资源 document_GetresourceText 获取指定url的内容 包括页面图片 下载地址下载地址 密码:upr47x...

开飞色
今天
44
0
关于DCL双重锁失效及解决方案

关于DCL双重锁失效及解决方案 Double Check Lock (DCL)实现单例 DCL 方式实现单例的优点是既能够在需要时才初始化单例,又能够保证线程安全,且单例对象初始化后调用getInstance方法不进行...

DannyCoder
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部