转自:http://dlwang2002.cnblogs.com/archive/2005/10/31/265810.html
实现目标
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技术, // 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,然后重新加载 就可以