我正在开发需要支持插件不同程度隔离的系统。我选择了 MAF,因为它符合我的需求,支持开箱即用的单独进程隔离和 AppDomain 隔离。
下面的示例使用了单独的进程隔离:
AddInStore.Rebuild(path);
...
var ap = new AddInProcess();
ap.Start();
var addin = token.Activate<MyAddInBase>(ap, AddInSecurityLevel.FullTrust);
但是,我在使 MAF 与主机和插件之间共享的库一起工作时遇到了问题。假设,我有项目(带有输出目录):
- My.MainApp -> /.
- My.AddIn.Hosting -> /.
- My.AddIn.Shared -> /.
- My.AddIn.Contract -> /contracts
- My.PlugIn.HostSideAdapter -> /HostSideAdapters
- My.PlugIn.PlugInSideAdapter -> /PlugInSideAdapter
- My.PlugIn.AddIn -> /AddInViews
- My.SamplePlugin -> /addins/SamplePlugin
和参考资料
My.MainApp <- My.AddIn.Hosting (copy local = true)
My.AddIn.Hosting <- My.AddIn.Shared (copy local = true)
<- My.AddIn.Contract (copy local = false)
My.PlugIn.AddIn <- My.AddIn.Contract (copy local = false)
My.PlugIn.HostSideAdapter <- My.AddIn.Hosting (copy local = false)
<- My.AddIn.Contract (copy local = false)
My.PlugIn.PlugInSideAdapter <- My.PlugIn.AddIn (copy local = false)
<- My.AddIn.Contract (copy local = false)
My.SamplePlugin <- My.PlugIn.AddIn (copy local = false)
<- My.AddIn.Contract (copy local = false)
这给了我一个干净的构建,每个管道目录中都有单个 dll,一切正常,管道已构建,有效且工作。
直到我添加有问题的:
My.AddIn.Shared <- My.AddIn.Contract (copy local = false)
My.AddIn.Hosting <- My.AddIn.Shared (copy local = false)
My.PlugIn.AddIn <- My.AddIn.Shared (copy local = false)
这引入了一个问题,因为 My.PlugIn.AddIn 项目不能包含在管道中,因为:
- 加载 My.PlugIn.AddIn 时出现问题 - 无法找到依赖项 My.AddIn.Shared(如果 AddInViews 包含带有插件库的单个 dll)
- 无法将透明代理转换为我的 IContract 类型 - (当 colyLocal=true 并且 AddInViews 包含超过 1 个 dll 时)
此外,值得一提的是 My.PlugIn.AddIn 中只有单个类用 AddInBaseAttribute 修饰,共享程序集没有单个类。
因此,在这两种情况下都无法加载插件。我想通过我的自定义事件处理程序来解决问题
AppDomain.CurrentDomain.AssemblyResolve
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve
在调用 AddInStore.Rebuild 之前,但这只会影响我的主机应用程序正在运行的域,并且不会影响由 System.AddIn.Hosting.AddInStore 在内部创建的域“加载项模型发现工作者 AD”
由于此类是静态的,因此无法覆盖域的创建。此外,它不提供任何允许我访问内部域解决错误的事件。有什么方法可以注入我的自定义程序集解析规则或强制内部 appDomain 从我的主程序继承解析事件?