实现目标

1:所加载的dll分布在不同的文件夹下,可以不再运行目录bin下。以创建AppDomain的方式加载/卸载
2:运行中可以自动监测dll的版本,如果dll又更新,则自动卸载原来的dll,重新加载新的程序集(当然也就得必须可以替换正在运行中的dll)
3:加载程序集中的类可以访问主程序域的方法(主程序域中的类当然可以访问自程序域中的实例的方法)

优点:

1:可以在运行中替换具体实现,不需要停止程序再加载
2:在不同程序域里的实现互相隔离,代码运行比较安全,一个实现出了问题,可以只卸载那一个AppDomain就可以

几个问题:

1:子程序域中无法访问主程序域中的一些配置文件,比如app.config
2:运行速度会慢一些,因为需要反复的 序列化/反序列化 。
3:调试复杂,不同程序域的调试就像递归函数一样,难以调试
4:不再是传实例引用,所有的都是传值的方式。

实现思路:

1:通过创建不同的AppDomain来加载dll,通过卸载AppDomain来卸载dll
2:通过一个Proxy类(继承自MarshalByRefObject)来访问具体的实现,一定不能返回具体实现的实例,而是要通过传递参数,在代理中执行,然后返回结果
3:子程序域中实现通过一个ProxyBack(MarshalByRefObject)的代理来访问主程序域中的方法,这个ProxyBack使用TCP信道来通讯 (Microsoft .Net Remoting)
4:所有需要在不同域之间传递的参数/返回值 都必须是可以序列化的。
5:制作一个DLLWatcher来监视dll所在文件夹的状态

具体实现:

1:代理类 创建不同的程序域 访问子程序域中的方法
http://dlwang2002.cnblogs.com/archive/2005/10/18/257425.html

2:使用Microsoft .Net Remoting技术,制作ProxyBack
关于Microsoft .Net Remoting技术,Wayfarer's Prattle有很详细的解释http://www.cnblogs.com/wayfarer/archive/2004/07/30/28723.html

这里主要看这几个主要的实现和注意事项

这是代理的Server端,在乎程序域中启动,侦听
public ProxyBackServer()
{
if(!isStart)
{
TcpChannel chan = new TcpChannel(8085);
ChannelServices.RegisterChannel(chan);

RemotingConfiguration.RegisterWellKnownServiceType(typeof( xxx.ProxyBackServer),
"CallLocalSM",WellKnownObjectMode.SingleCall);
isStart=true;
}
方法:注意所传递的都必须是可以序列化的对象,在需要加载dll的文件夹下也要有这个传递对象实现的程序集。
public IStateDictionary RunService(IStateDictionary request)

在这个Server的析构函数中要释放这个TCP信道

~ProxyBackServer()
// {
// IChannel[] channels = ChannelServices.RegisteredChannels;
// //关闭指定名为CallLocalSM的通道;
// foreach (IChannel eachChannel in channels)
// {
// if (eachChannel.ChannelName == "CallLocalSM")
// {
// TcpChannel tcpChannel = (TcpChannel)eachChannel;
//
// //关闭监听;
// tcpChannel.StopListening(null);
//
// //注销通道;
// ChannelServices.UnregisterChannel(tcpChannel);
// }
// }
//
// }

这是代理的Client端,子程序域访问主程序域的时候使用
public ProxyBackClient()
{
if(!isReg)// boot once
{
TcpChannel chan = new TcpChannel();
ChannelServices.RegisterChannel(chan);
isReg=true;
}
_server = (ProxyBackServer)Activator.GetObject(
typeof(xxxx.ProxyBackServer), "tcp://localhost:8085/CallLocalSM");
if (_server == null)
{
throw new Exception("can not connect to local host to get instance of sm");
}

}
public IContext RunService(IContext ctx)
{
try
{
ctx.Response= this._server.RunService(ctx.Request);
return ctx;
..........

}

}

3:DllWatcher

............

_mask = "*.dll";
// initialize watcher to watch the process directory
this.dllWatcher = new FileSystemWatcher();
this.dllWatcher .Path = _path;
this.dllWatcher .Filter = _mask;
this.dllWatcher .Changed += new FileSystemEventHandler(File_OnChanged);
this.dllWatcher .Created += new FileSystemEventHandler(File_OnChanged);
this.dllWatcher .Deleted += new FileSystemEventHandler(File_OnChanged);
// tell it to start watching
this.dllWatcher .EnableRaisingEvents = true;
在接收到事件之后,调用主域中的方法卸载AppDomain,然后重新加载 就可以

转载于:https://www.cnblogs.com/blogpro/p/11458305.html

完整的动态加载卸载程序集的解决方案相关推荐

  1. C#中动态加载卸载类库

    网上现有很多的文章是介绍怎样开发插件化的框架的,大部分无非是用Assembly.load等方法,动态加载类库,但这种方法有个缺点,就是没有办法卸载,因为net中就没有提供卸载assembly的方法,还 ...

  2. js插件动态加载js、css解决方案

    最近因为工作需要做了一个js自动导入的插件,一开始很天真的以为动态创建个script添加到head中就ok了,试了之后才发现了问题,就是如果同时引入了多个js文件,而且后一个文件中用到了前一个文件中的 ...

  3. 关于c#中 的动态加载程序集

    最近在写一个解析分析程序,需要动态加载卸载程序集(其实就是一个简单的插件框架),我的 思路是在主程序的目录下,创建一个assemblis目录,用来存放插件目录,如果加载插件时将其复制到 此目录,然后主 ...

  4. 【Linux 内核】宏内核与微内核架构 ( 操作系统需要满足的要素 | 宏内核 | 微内核 | Linux 内核动态加载机制 )

    文章目录 一.操作系统需要满足的要素 二.宏内核 三.微内核 四.Linux 内核动态加载机制 一.操作系统需要满足的要素 电脑上运行的 操作系统 , 是一个 软件 ; 设备管理 : 操作系统需要 为 ...

  5. Android动态加载技术三个关键问题详解

    本文摘选自任玉刚著<Android开发艺术探索>,介绍了Android插件化技术的原理和三个关键问题,并给出了作者自己发起的开源插件化框架. 动态加载技术(也叫插件化技术)在技术驱动型的公 ...

  6. Android插件化开发之动态加载三个关键问题详解

    本文摘选自任玉刚著<Android开发艺术探索>,介绍了Android插件化技术的原理和三个关键问题,并给出了作者自己发起的开源插件化框架. 动态加载技术(也叫插件化技术)在技术驱动型的公 ...

  7. Unity3d(UE4)动态加载osgb倾斜摄影数据

    在Unity3D平台动态加载调度倾斜摄影数据,利用多线程动态加载瓦片数据,可以顺畅加载海量的瓦片数据.目前测试可流畅加载200G左右数据,支持加载本地数据,数据可不放在Unity工程内,也可以将数据放 ...

  8. BPL 和动态加载包

    BPL 是一种特别的 DLL: 使用 Delphi 开发程序,可以把一个大程序的一部分,独立编译成一个 BPL,一个 Delphi 里面称作 Package 的东西,这里中文我们称作[包],然后让 E ...

  9. C#.Net 如何动态加载与卸载程序集(.dll或者.exe)6-----在不卸载程序域的前提下替换程序集文件。...

    原文:C#.Net 如何动态加载与卸载程序集(.dll或者.exe)6-----在不卸载程序域的前提下替换程序集文件. 当某个程序集文件被载入AppDomain,该文件在AppDomain.Unloa ...

  10. C#.Net 如何动态加载与卸载程序集(.dll或者.exe)0-------通过应用程序域AppDomain加载和卸载程序集...

    本博客中以"C#.Net 如何动态加载与卸载程序集(.dll或者.exe)"开头的都是引用莫问奴归处 微软装配车的大门似乎只为货物装载敞开大门,却将卸载工人拒之门外.车门的钥匙只有 ...

最新文章

  1. ArcGIS API for Silverlight 当DataGrid选中项时,地图聚焦弹出窗口,并可以播放音频文件...
  2. AppCode iOS 应用开发 开发环境
  3. Python学习总结5:数据类型及转换
  4. python coding_Python终极coding
  5. 关于 someone could be eavesdropping on you right now (man-in-the-middle attack) ssh的解决办法
  6. C++中使用set和unordered_set的find方法时遇到的小坑
  7. f5在运营商计费系统中的版本升级割接详细步骤
  8. ELK下Kibana和Elasticsearch之间相互TLS身份验证
  9. 二十年后我发明了保姆机器人作文_小学生作文“二十年后的我”走红,老师看完气愤,让学生站着听课...
  10. C++ 编译发现 error C2146: syntax error : missing ';' before identifier 'm_ctrlserver'
  11. web项目搜索框智能提示
  12. 乐安全 支持x86_android-x86-4.4-r2运行程序总是停止运行怎么处理
  13. 软件计算机考研考英语几,软件工程考研考哪几科
  14. KETTLE使用教程(包含几个小示例)
  15. 易语言逐条读access数据_易语言数据库教程之ACCESS数据库全操作
  16. Android RTSP IPC的使用
  17. Mybatis 批量更新运行异常,数据库 postgres
  18. 我爬取了淘宝零食库,画了一个全国零食地图
  19. 常用软件国内源镜像地址大全
  20. NoSQLBooster for MongoDB延长使用时间

热门文章

  1. excel小写转大写公式_EXCEL人民币金额小写转大写
  2. session和coolie的区别
  3. 简述cookie增删改查的函数封装
  4. 直流斩波电路在matlab中的建模与仿真,毕业设计直流斩波电路的MATLAB建模与仿真...
  5. python数据分析之航空公司客户价值分析
  6. 二倍图三倍图什么意思_小程序有二倍图三倍图使用的必要吗?
  7. MPEG LA提供一站式ATSC 3.0许可证
  8. Pollard-rho的质因数分解
  9. vue 解决控制台Prop being mutated: “placement“报错
  10. 讲解HTML和CSS(超详细)