WPF 跨应用程序域的 UI(Cross AppDomain UI)
为自己写的程序添加插件真的是一个相当常见的功能,然而如果只是简单加载程序集然后去执行程序集中的代码,会让宿主应用程序暴露在非常危险的境地!因为只要插件能够运行任何一行代码,就能将宿主应用程序修改得天翻地覆哭爹喊娘;而根本原因,就在于暴露了整个托管堆和整个 UI 树。
如果将宿主和插件放到不同的应用程序域中,则可以解决此问题。本文将介绍跨应用程序域承载 UI 的方法,其中也包含跨域(Cross-Domain)调用方法。
来自于托管插件框架的辅助类
.NET Framework 自 3.5 以来推出了托管插件框架(MAF,Managed AddIn Framework),位于 System.AddIn 命名空间。其特性在于,将宿主和插件隔离在不同的应用程序域中,避免插件对宿主造成不良影响。
此命名空间中存在 FrameworkElementAdapters 类型,在 System.Windows.Presentation 程序集中,详见 FrameworkElementAdapters.cs。虽说主要用于 MAF 插件框架,但其实只需要此类型便可以实现跨应用程序域的 UI。
FrameworkElementAdapters 只有两个方法,ViewToContractAdapter 将 UI 转换成 INativeHandleContract,而 ContractToViewAdapter 将 INativeHandleContract 用一个 FrameworkElement 进行承载。
public static class FrameworkElementAdapters
{
[SecurityCritical]
public static FrameworkElement ContractToViewAdapter(INativeHandleContract nativeHandleContract);
[SecurityCritical]
public static INativeHandleContract ViewToContractAdapter(FrameworkElement root);
}
一个极简的跨域 UI Demo
首先,我们需要有一个支持跨域调用的类型,并有任意的可以用来返回 INativeHandleContract 的方法。
internal sealed class DomainX : MarshalByRefObject
{
public INativeHandleContract GetElement()
{
return FrameworkElementAdapters.ViewToContractAdapter(
new Rectangle
{
Width = 200,
Height = 100,
Fill = Brushes.ForestGreen,
});
}
}
我们需要跨域创建这个 UI 控件并得到 INativeHandleContract。
var domain = AppDomain.CreateDomain("X");
var instance = (DomainX)domain.CreateInstanceAndUnwrap(typeof(DomainX).Assembly.FullName, typeof(DomainX).FullName);
var contract = instance.GetElement();
然后,在需要承载这个跨域 UI 的地方取得这个 INativeHandleContract 的实例 contract。
var element = FrameworkElementAsyncAdapters.ContractToViewAdapter(contract);
// this 在这里是 MainWindow 或者 MainPage,或者其它任何能够承载 FrameworkElement 的对象。
this.Content = element;
以上的这两端代码都可以写在 MainWindow 的 Loaded 事件中。
对 MAF 吐一下槽
MAF 框架对插件和宿主程序集所在的文件夹结构有要求。这可是非常讨厌的一项特性!因为当我们希望采用 MAF 框架的时候,我们的应用程序可能已经有自己独特的一套目录了。就算我们从零开始写应用,采用 MAF 约定的方式组织 dll 也是很丑的方式(带有很重的 MAF 的影子)。
它没有提供任何的配置,而且如果不按照约定放置文件夹,还会发生如下错误:
参考资料
- ENikS/System.AddIn: Projects related to Microsoft System.AddIn
- Add-In Performance: What can you expect as you cross an isolation boundary and how to make it better [Jesse Kaplan] – CLR Add-In Team Blog
- WPF Add-Ins Overview - Microsoft Docs
- Walkthrough: Creating an Extensible Application - Microsoft Docs
- Add-ins and Extensibility - Microsoft Docs
WPF 跨应用程序域的 UI(Cross AppDomain UI)的更多相关文章
- 跨应用程序域(AppDomain)的单例(Singleton)实现
转载自: 跨应用程序域(AppDomain)的单例(Singleton)实现 - CorePlex代码库 - CorePlex官方网站,Visual Studio插件,代码大全,代码仓库,代码整理,分 ...
- WPF 同一窗口内的多线程/多进程 UI(使用 SetParent 嵌入另一个窗口)
原文 WPF 同一窗口内的多线程/多进程 UI(使用 SetParent 嵌入另一个窗口) WPF 的 UI 逻辑只在同一个线程中,这是学习 WPF 开发中大家几乎都会学习到的经验.如果希望做不同线程 ...
- 解析.NET对象的跨应用程序域访问--AppDomain(上篇)
在目前的项目开发中,分布式开发已经逐渐成为主流.一个项目要是没有采用分布式架构,都不好意思跟别人说这是一个完整的项目.这句话虽然有些过激,但是随着人们对效率的要求在提高,以及产品需要提升用户体验.只有 ...
- 如何跨线程访问Winform中的UI元素
如何跨线程访问Winform中的UI元素 假如制作一个Socket聊天应用程序,很可能会用到多线程: 例如为Receive方法开辟单独一个线程,例如为Receive方法开辟单独一个线程(后台运行的线程 ...
- 【.net 深呼吸】跨应用程序域执行程序集
应用程序域,你在网上可以查到它的定义,凡是概念性的东西,大伙儿只需要会搜索就行,内容看了就罢,不用去记忆,更不用去背,“名词解释”是大学考试里面最无聊最没水平的题型. 简单地说,应用程序域让你可以在一 ...
- 面向UI编程:ui.js 1.0 粗糙版本发布,分布式开发+容器化+组件化+配置化框架,从无到有的艰难创造
时隔第一次被UI思路激励,到现在1.0的粗糙版本发布,掐指一算整整半年了.半年之间,有些细节不断推翻重做,再推翻再重做.时隔今日,终于能先出来个东西了,这个版本很粗糙,主体功能大概能实现了,但是还是有 ...
- 解析.NET对象的跨应用程序域访问(下篇)
转眼就到了元宵节,匆匆忙忙的脚步是我们在为生活奋斗的写照,新的一年,我们应该努力让自己有不一样的生活和追求.生命不息,奋斗不止.在上篇博文中主要介绍了.NET的AppDomain的相关信息,在本篇博文 ...
- 解析.NET对象的跨应用程序域访问(上篇)
在目前的项目开发中,分布式开发已经逐渐成为主流.一个项目要是没有采用分布式架构,都不好意思跟别人说这是一个完整的项目.这句话虽然有些过激,但是随着人们对效率的要求在提高,以及产品需要提升用户体验.只有 ...
- NET对象的跨应用程序域
NET对象的跨应用程序域 转眼就到了元宵节,匆匆忙忙的脚步是我们在为生活奋斗的写照,新的一年,我们应该努力让自己有不一样的生活和追求.生命不息,奋斗不止.在上篇博文中主要介绍了.NET的AppDoma ...
随机推荐
- SVN 与Eclipse 关联 || 安装beyond 插件
1.让本地svn代码与库建立联系 右击项目名称,Team - share project 2.本地svn版本一般与Eaclipse svn插件 版本一致!http://subclipse.tig ...
- Linux安装keepalived
1.下载安装ipvs安装包,进行解压 http://www.keepalived.org/software/ 2.创建安装路径连接 安装环境: yum -y install openssl-devel ...
- Normalize.css与CSS reset区别
Normalize.css 只是一个很小的CSS文件,但它在默认的HTML元素样式上提供了跨浏览器的高度一致性.相比于传统的CSS reset,Normalize.css是一种现代的.为HTML5准备 ...
- HTML5 history API,创造更好的浏览体验
HTML5 history API有什么用呢? 从Ajax翻页的问题说起 请想象你正在看一个视频下面的评论,在翻到十几页的时候,你发现一个写得稍长,但非常有趣的评论.正当你想要停下滚轮细看的时候,手残 ...
- IdentityServer4在Asp.Net Core中的应用(三)
今天的内容是授权模式中的简化模式,还是先看以下授权流程图: 在这种模式中我们将与OpenID结合使用,所以首先我们要了解OpenID和OAuth的区别,关于他们的区别,在我上一篇博客<理解Ope ...
- CSS3:@font-face规则
前言 过去,Web设计师为了保证网站能够正常显示,只能使用“Web安全字体”,即每台机器都预装的字体.但Web安全字体有时并不好看... @font-face能够使得任何一台机器能够显示理想中的字体. ...
- 超好用的ip归属区域查询
源码如下: #!/usr/bin/env python#-*-coding:utf-8-*- import requestsfrom bs4 import BeautifulSoupimport re ...
- c# 计算中文字节数与JAVA不符的解决方法
c# 中方法 string str = "中华人民共和国"; int strLen = System.Text.Encoding.Default.GetByteCount(str) ...
- UVALive-3523 Knights of the Round Table (双连通分量+二分图匹配)
题目大意:有n个骑士要在圆桌上开会,但是相互憎恶的两个骑士不能相邻,现在已知骑士们之间的憎恶关系,问有几个骑士一定不能参加会议.参会骑士至少有3个且有奇数个. 题目分析:在可以相邻的骑士之间连一条无向 ...
- hdu2853
题解: KM算法模板 然后我把另一边加了点 然后写了#define int long long 然后莫名挂... 然后去掉就过了 代码: #include<cstdio> #include ...