using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Input; namespace PluginDemo { public interface IPlugin { int GetInt(); string GetString(); object GetNonMarshalByRefObject(); Action GetAction(); List<string> GetList(); } }
接口 IPlugin
在另外的一个程序集中有其一个实现类 Plugin:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using PluginDemo; namespace PluginDemo.NewDomain { 支持跨应用程序域访问 Plugin : MarshalByRefObject, IPlugin { length; int 作为基础数据类型, 是持续序列化的. GetInt() { length += new Random().Next(10000); return length; } string 作为特殊的class, 也是持续序列化的. GetString() { ; } 未继承 MarshalByRefObject 并且 不支持序列化 的 class, 是不可以跨AppDomain通信的,也就是说其他AppDomain是获取不到其对象的 GetNonMarshalByRefObject() { return new NonMarshalByRefObject(); } private NonMarshalByRefObjectAction obj = new NonMarshalByRefObjectAction(); 委托,和 委托所指向的类型相关 Action GetAction() { obj.Add(); obj.Add(); obj.TestAction; } , }; 也是持续序列化的, 当然前提是T也必须支持跨AppDomain通信 List<string> GetList() { return this.list; // return new List<Action>() { this.GetAction() }; } } }
实现类 Plugin在另外的一个程序集中还有一个
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace PluginDemo.NewDomain { 未继承 MarshalByRefObject, 不可以跨AppDomain交换消息 NonMarshalByRefObject { } }
空类型 NonMarshalByRefObject
测试程序如下:
using System; using System.Windows; using System.Diagnostics; using System.Runtime.Serialization.Formatters.Binary; namespace PluginDemo { MainWindow.xaml 的交互逻辑 MainWindow : Window { private AppDomain domain; private IPlugin remoteIPlugin; public MainWindow() { InitializeComponent(); } private void loadBtn_Click(object sender, RoutedEventArgs e) { try { unLoadBtn_Click(sender, e); this.txtBlock.Text = string.Empty; // 在新的AppDomain中加载 RemoteCamera 类型 AppDomainSetup objSetup = new AppDomainSetup(); objSetup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory; objSetup.ShadowCopyFiles = ; // 虽然此方法已经被标记为过时方法, msdn备注也提倡不使用该方法, // 但是 以.net 4.0 + win10环境测试,还必须调用该方法 否则,即便卸载了应用程序域 dll 还是未被解除锁定 AppDomain.CurrentDomain.SetShadowCopyFiles(); , null, objSetup); , ).Unwrap() as IPlugin; ); } catch (Exception ex) { this.txtBlock.AppendText(ex.Message); ); } } private void unLoadBtn_Click(object sender, RoutedEventArgs e) { if (this.remoteIPlugin != null) { this.remoteIPlugin = null; } if (this.domain != null) { AppDomain.Unload(this.domain); this.domain = null; ); } } private void invokeBtn_Click(object sender, RoutedEventArgs e) { if (this.remoteIPlugin == null) return; ); ); try { this.remoteIPlugin.GetNonMarshalByRefObject(); } catch (Exception ex) { ); if (Debugger.IsAttached) { Debugger.Break(); } } } } }
测试程序按测试程序代码执行,先Load AppDomain, 然后 Access Other Member, 此时会发现出现了异常,大致内容如下:
创建AppDomain成功