AppDomain卸载与代理

涉及内容:

  • 反射与MEF解决方案
  • AppDomain卸载与代理
  • WinForm、WcfRestService示

插件系统的基本目的是实现宿主与组件的隔离,核心是作为接驳约定的接口,宿主使用类型发现及挂载插件,以下是反射实现。

创建类库项目Plugin,添加接口IPlugin:

 

创建控制台程序HostApp,添加对Plugin项目的引用,Main方法代码:

创建类库项目MyPlugin1,添加对Plugin项目的引用,添加Plugin1类并实现IPlugin:

修改该项目的属性,在“生成”选项卡中找到输出,将“输出路径”指向HostApp下的bin\Debug文件夹,运行。

宿主使用无参的IPlugin子类完成组件调用。代码逻辑并不复杂但我们还有更优雅的解决方式即MEF框架,这里拿MEF的完成所需功能,组件生命周期等内容并不深入讨论,如有需求请自行MSDN。

MEF框架以Import、Export特性为功能入口,修改MyPlugin项目,引用System.ComponentModel.Composition,为MyPlugin添加Export特性:

注意Export明确指定导出类型为IPlugin,在Plugin项目中添加类PluginProvider,引用System.ComponentModel.Composition和System.ComponentModel.Composition.Hosting,添加IEnumerable<Lazy<IPlugin>>类型只读属性并标注ImportMany特性:

抽象基类ComposablePartCatalog表示组件目录,子类DirectoryCatalog使用指定目录进行搜索。PluginProvider使用了当前程序运行目录作为dll路径。同时导入点所在字段或属性可以是IEnumerable<T>、IEnumerable<Lazy<T>>、IEnumerable<Lazy<T, TMetadata>>等,延迟绑定能相对降低内存开销,这里使用了第2种,接着修改Main方法:

运行得到同样的结果,代码更加优雅;根据需求,修改PluginProvider的导入逻辑及使用泛型版本,将得到更多的灵活性。代码文件

前一篇文章简单展示了类型发现和MEF使用,本文初步进入AppDomain相关内容。

CLR程序运行时会创建默认程序集容器即AppDomain,默认AppDomain不支持卸载其程序集,但CLR支持创建和卸载AppDomain,这意味着我们可以间接地通过额外的AppDomain实现插件的热插拔。

代理AppDomain创建PluginProvider实例,该实例及其发现的IPlugin的实现需要被被默认AppDomain访问,于是发生了跨AppDomain边界的访问,PluginProvider及IPlugin的具体实现需要由MarshalByRefObject派生(更多相关内容仍然需要自行MSDN)。

为Plugin项目添加PluginProxy类,该类负责维护上述的额外AppDomain、将PluginProvider封送回默认AppDomain。本例仅设计了单个插件容器的场景,故以单例模式实现:

AppDomain的创建与跨边界访问对象的成本很高,后文中默认AppDomain与插件的交互将以代理PluginProxy通知PluginProvider的方式实现。Plugin中PluginProvider小幅修改:

MyPlugin1中Plugin1小幅修改:

主程序PluginProxy由静态类属性访问,同时加入逻辑检验DLL可否在AppDomain卸载后删除,WinForm与WCFRestService示例在后续给出。代码文件

附求职:寻求.Net相关职位,偏向后端,目前人在北京,有意请邮件jusfr.v#gmail.com,请替换#为@,沟通后奉上简历。

AppDomain卸载与代理的更多相关文章

  1. 动态加载与插件系统的初步实现(二):AppDomain卸载与代理

    前一篇文章简单展示了类型发现和MEF使用,本文初步进入AppDomain相关内容. CLR程序运行时会创建默认程序集容器即AppDomain,默认AppDomain不支持卸载其程序集,但CLR支持创建 ...

  2. 动态加载与插件系统的初步实现(一):反射与MEF解决方案

    涉及内容: 反射与MEF解决方案 AppDomain卸载与代理 WinForm.WcfRestService示 PRRT1: 反射实现 插件系统的基本目的是实现宿主与组件的隔离,核心是作为接驳约定的接 ...

  3. 卸载AppDomain动态调用DLL异步线程执行失败

    应用场景 动态调用DLL中的类,执行类的方法实现业务插件功能 使用Assembly 来实现 但是会出现逻辑线程数异常的问题 使用AppDomain 实现动态调用,并卸载. 发现问题某个插件中开启异步线 ...

  4. .NET跨AppDomain访问对象

    什么是AppDomain? 我们都知道windows进程,它起到应用程序隔离的作用,带来的好处是,当某个进程发生错误的时候,不会影响其他的进程,系统也不会受到影响.但是,创建windows进程的代价是 ...

  5. 第二节:AppDomain

    CLR COM服务器初始化时,会创建一个AppDomain.AppDomain是一组程序集的逻辑容器.CLR初始化时创建的第一个AppDomain称为默认的AppDomain,这个默认的AppDoma ...

  6. C#.Net 如何动态加载与卸载程序集(.dll或者.exe)5-----Assembly.Unload

    http://www.blogcn.com/user8/flier_lu/index.html?id=2164751&run=.04005F8 CLR 产品单元经理(Unit Manager) ...

  7. .Net AppDomain详解(二)

    AppDomain 类 表示应用程序域,它是一个应用程序在其中执行的独立环境. 此类不能被继承. 命名空间:   System程序集:  mscorlib(位于 mscorlib.dll) 继承层次结 ...

  8. CLR寄宿和AppDomain

    一.CLR寄宿 .net framework在windows平台的顶部允许.者意味着.net framework必须用windows能理解的技术来构建.所有托管模块和程序集文件必须使用windows ...

  9. 第22章 CLR寄宿和AppDomain

    22.1 CLR寄宿 CLR Hosting(CLR 宿主)的概念:初始启动.Net Application时,Windows进程的执行和初始化跟传统的Win32程序是一样的,执行的还是非托管代码,只 ...

随机推荐

  1. 怎样将IPhone应用程序软件公布到应用程序商店?

    转自:http://www.shtion.com/667.html 怎样将IPhone应用程序软件公布到应用程序商店? 2009年10月19日公布 分类: App store, iphone, 手机应 ...

  2. IS2009制作Oracle 静默安装包(二) 感谢空白先生特许授权

    原文:IS2009制作Oracle 静默安装包(二) 感谢空白先生特许授权 上一篇: IS2009制作Oracle 静默安装包(一)感谢空白先生特许授权本文经原作者特许授权于海洋女神发布,转载请务必注 ...

  3. Mybatis包分页查询java公共类

    Mybatis包分页查询java公共类   分页----对于数据量非常大的查询中.是不可缺少的. mybatis底层的分页sql语句因为须要我们自己去手动写.而实现分页显示的时候我们须要依据分页查询条 ...

  4. Spring AspectJ的Execution表达式-备忘笔记

    Aspectj切入点语法定义 在使用spring框架配置AOP的时候,不管是通过XML配置文件还是注解的方式都需要定义pointcut"切入点" 例如定义切入点表达式  execu ...

  5. 文件合并工具DiffMerge发布4.2版本

    DiffMerge一直是文件对比合并工具的佼佼者,其最大特点是多文件对比与合并,并提供可视化界面用于编辑. 此次DiffMerge v4.2发布,提高了文件差异对比,并提供了快速匹配功能,以及更好的用 ...

  6. Keil中使用宏编译来定义DEBUG输出

    使用宏编译来格式化调试信息,是一个不错的方法,即可以在需要的时候打印出信息,还可以格式化我们所需要的输出. #define DEBUG 1 #if (DEBUG == 1) #define DBG(A ...

  7. Java泛型和集合之泛型介绍

    在声明一个接口和类的时候可以使用尖括号带有一个或者多个参数但是当你在声明属于一个接口或者类的变量的时候或者你在创建一个类实例的时候需要提供他们的具体类型.我们来看下下面这个例子 List<Str ...

  8. hdu 1059 Dividing 多重背包

    点击打开链接链接 Dividing Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  9. 探索Android该Parcel机制上

    一.先从Serialize说起 我们都知道JAVA中的Serialize机制.译成串行化.序列化……,其作用是能将数据对象存入字节流其中,在须要时又一次生成对象.主要应用是利用外部存储设备保存对象状态 ...

  10. 处理动态SQL语句的参数

    原文:处理动态SQL语句的参数 经常对SQL进行开发,写动态的SQL语句,是少之不了的,但是在使用动态语句中,常是因为有动态的参数的出现.参考下面代码示例: 正因为有了标记1的动态条件代码,而让SQL ...