插件的“动态替换”
2015-08-13 20:50
134 查看
设想这样一种场景:我们的服务系统提供一系列的功能服务,而以后会有更多新的功能服务增加进来,也可能出现功能服务需要被更改或移除的情况。对于这样的服务系统,一个常见的基本的要求就是,在添加/移除/更新功能服务的时候不能停止的服务系统的运行。通常,将每一项服务封装成一个插件Dll,可以非常容易地实现“插件热插拔”(关于插件的基础信息,参见这里),但是插件的“热替换”(“动态替换”)却成了一个问题。原因在于,当我们从服务系统中卸载插件Dll的时候,实际上服务系统仍然持有该Dll的底层引用,这时如果你尝试删除或覆盖这个Dll,windows就会给出类似“该Dll正在被使用”的信息。
那么如何解决这个问题了?我觉得至少有两种方案:
(1)使用AppDomain。在一个新的AppDomain中加载插件,然后通过卸载这个AppDomain就可以干净地从服务系统中卸载该AppDomain中的插件Dll。这种方案的缺陷是需要管理众多的AppDomain(因为你有众多的功能服务),而且跨AppDomain的通信都是以Remoting的方式进行的,这将为我们的系统引入不少本不必要的麻烦。如果你有兴趣也可以尝试一下这种方案,而我更喜欢用第二种。
(2)在内存中复制插件Dll,然后加载内存中的Dll。这样,硬盘上的Dll就可以随意地被覆盖或删除了。以前我们是直接从硬盘加载插件Dll,就像这样:
现在,我们需要转个弯:
这样就解决了插件的“动态替换”的问题。
参考链接:
那么如何解决这个问题了?我觉得至少有两种方案:
(1)使用AppDomain。在一个新的AppDomain中加载插件,然后通过卸载这个AppDomain就可以干净地从服务系统中卸载该AppDomain中的插件Dll。这种方案的缺陷是需要管理众多的AppDomain(因为你有众多的功能服务),而且跨AppDomain的通信都是以Remoting的方式进行的,这将为我们的系统引入不少本不必要的麻烦。如果你有兴趣也可以尝试一下这种方案,而我更喜欢用第二种。
(2)在内存中复制插件Dll,然后加载内存中的Dll。这样,硬盘上的Dll就可以随意地被覆盖或删除了。以前我们是直接从硬盘加载插件Dll,就像这样:
Assembly asm = Assembly.LoadFrom(addinFilePath) ;
现在,我们需要转个弯:
Assembly asm = null ; //先将插件拷贝到内存缓冲 byte[] addinStream = null ; if(FileHelper.ReadFileToBuff(addinFilePath ,out addinStream)) { asm = Assembly.Load(addinStream) ; //加载内存中的Dll }
这样就解决了插件的“动态替换”的问题。
参考链接:
插件的“动态替换”
企业级服务器设计与实现经验之插件系统基础篇相关文章推荐
- ListView 添加footView导致崩溃的问题
- Android使用ImageLoader异步加载网络图片(一)读取单张图片
- find the nth digit
- Hdu 5386 Cover 拓扑排序
- Colored Sticks(POJ--2513
- 多线程
- HashMap详解
- 线段树hdu1166
- 一起talk C栗子吧(第三十五回:C语言实例--测试程序运行时间)
- 博客流量分析
- SOAPUI 使用groovy发送http请求 自动化测试
- STM32——GPIO输入模式下上拉和下拉的设置
- Android-项目开发基础—JNI与底层调用(十三)
- Conscription 3723(最小生成树变形)
- UILabel用法大全
- layoutSubviews何时调用的问题
- UITabBarController 标签导航控制器的使用
- css初始样式设置
- c/c++中产生随机数
- sql server2008R2易出现的错误