动态加载与插件系统的初步实现(二):AppDomain卸载与代理
来源:互联网 发布:java中把实参打印出来 编辑:程序博客网 时间:2024/06/03 19:50
前一篇文章简单展示了类型发现和MEF使用,本文初步进入AppDomain相关内容。
CLR程序运行时会创建默认程序集容器即AppDomain,默认AppDomain不支持卸载其程序集,但CLR支持创建和卸载AppDomain,这意味着我们可以间接地通过额外的AppDomain实现插件的热插拔。
代理AppDomain创建PluginProvider实例,该实例及其发现的IPlugin的实现需要被被默认AppDomain访问,于是发生了跨AppDomain边界的访问,PluginProvider及IPlugin的具体实现需要由MarshalByRefObject派生(更多相关内容仍然需要自行MSDN)。
为Plugin项目添加PluginProxy类,该类负责维护上述的额外AppDomain、将PluginProvider封送回默认AppDomain。本例仅设计了单个插件容器的场景,故以单例模式实现:
public class PluginProxy{ private readonly static PluginProxy instance = new PluginProxy(); private PluginProxy() { } public static PluginProxy Instance { get { return instance; } } private AppDomain pluginDomain = null; private PluginProvider pluginProvider = null; public PluginProvider Provider { get { if (pluginDomain == null) { pluginDomain = AppDomain.CreateDomain("PluginDomain"); Type pluginProviderType = typeof(PluginProvider); pluginProvider = (PluginProvider)pluginDomain.CreateInstanceAndUnwrap(pluginProviderType.Assembly.FullName, pluginProviderType.FullName); } return pluginProvider; } } public void Unload() { if (pluginDomain != null) { AppDomain.Unload(pluginDomain); pluginDomain = null; } }}
AppDomain的创建与跨边界访问对象的成本很高,后文中默认AppDomain与插件的交互将以代理PluginProxy通知PluginProvider的方式实现。Plugin中PluginProvider小幅修改:
public class PluginProvider : MarshalByRefObject{ [ImportMany] public IEnumerable<Lazy<IPlugin>> Plugins { get; private set; } public PluginProvider() { AggregateCatalog catalog = new AggregateCatalog(); catalog.Catalogs.Add(new DirectoryCatalog(".")); CompositionContainer container = new CompositionContainer(catalog); container.ComposeParts(this); }}
MyPlugin1中Plugin1小幅修改:
[Export(typeof(IPlugin))]public class Plugin1 : MarshalByRefObject, IPlugin{ public String DoStuff() { return "MyPlugin1 Plugin1.DoStuff"; }}
主程序PluginProxy由静态类属性访问,同时加入逻辑检验DLL可否在AppDomain卸载后删除,WinForm与WCFRestService示例在后续给出。代码文件
class Program{ static void Main(string[] args) { PluginProvider pluginProvider = PluginProxy.Instance.Provider; foreach (Lazy<IPlugin> plugin in pluginProvider.Plugins) { Console.WriteLine(plugin.Value.DoStuff()); } PluginProxy.Instance.Unload(); String filename = "MyPlugin1.dll"; if (File.Exists(filename)) { File.Delete(filename); Console.WriteLine("File deleted"); } else { Console.WriteLine("File not exist"); } Console.WriteLine("Press Enter to exit"); Console.ReadLine(); }}
附求职:寻求.Net相关职位,偏向后端,目前人在北京,有意请邮件jusfr.v#gmail.com,请替换#为@,沟通后奉上简历。
<script type="text/javascript"><!--google_ad_client = "ca-pub-1944176156128447";/* cnblogs 首页横幅 */google_ad_slot = "5419468456";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
- 动态加载与插件系统的初步实现(二):AppDomain卸载与代理
- AppDomain与Assembly的动态加载与卸载
- 动态加载与插件系统的初步实现(三):WinForm示例
- 动态加载与插件系统的初步实现(四):解析JSON、扩展Fiddler
- C#中动态加载卸载Appdomain
- AppDomain加载与释放dll
- linux中ELF文件动态链接的加载、解析及实例分析(二): 函数解析与卸载
- Linux系统(二)软件的安装与卸载
- Java 动态代理的理解与Cglib动态代理实现
- Java 静态加载类与动态加载类(初步认识Java的反射)
- wince驱动学习笔记(vs2005实现流驱动动态加载与卸载 1)
- wince驱动学习笔记(vs2005实现流驱动动态加载与卸载 2)
- wince驱动学习笔记(vs2005实现流驱动动态加载与卸载 2)
- wince驱动学习笔记(vs2005实现流驱动动态加载与卸载 1)
- AppDomain 和动态加载
- 动态加载与插件化
- 动态加载与插件化
- 静态代理与动态代理二
- IOS学习之IOS沙盒(sandbox)机制和文件操作(二)
- java类加载
- 八皇后问题
- Android 调整屏幕分辩率
- IOS学习之IOS沙盒(sandbox)机制和文件操作之NSFileManager(三)
- 动态加载与插件系统的初步实现(二):AppDomain卸载与代理
- 路由器和交换机的综合实验⑵
- Andorid时间控件和日期控件
- PC上实现AirPlay功能的软件
- 六月的雨
- MyBufferedWriter
- Struts2运行机制(MVC)的分析:
- ASIHTTPRequest下载示例(支持断点续传)
- linux下面安装配置LAMP环境