我的想法是让每个插件在不同的应用程序域中运行.问题似乎是我的主机应用程序应该有一组我的插件将要使用的服务以及我的理解是什么使数据流入和流出不同的应用程序域并不是一件好事.
一方面我希望它们像独立的应用程序一样(尽管如我所说,它们需要多次使用主机应用程序服务),但另一方面,如果它们中的任何一个崩溃,我会喜欢它,我的主要应用程序不会受此影响.
这种情况的最佳(.NET)方法是什么?让它们全部在同一个AppDomain上运行,但每个都在不同的线程中?使用不同的AppDomains?每个“插件”一个?我如何让他们与主机应用程序通信?这样做的其他任何方式?
虽然速度在这里不是问题,但我不希望函数调用比我们使用常规.NET应用程序时慢得多.
谢谢
编辑:也许我真的需要使用不同的AppDomains.从我读过的内容来看,在不同的AppDomain中加载程序集是以后能够从进程中卸载它们的唯一方法.
解决方法
您的主机应用程序和插件通过您从MAF接口派生的合同进行通信.您可以在主机和插件之间来回发送对象. cotnracts在插件和主机之间提供了一个黑盒接口,允许您更改主机不知道的插件实现.
如果主机告诉他们彼此之间的联系,它们甚至可以在它们之间进行通信.在我的例子中,其他人共享一个日志加载项.这让我可以放入不同的记录器,而不会触及其他插件或主机.
对于我的应用程序,addin使用简单的supervisor类,它们在自己的线程上的启动工作者类中执行所有处理.工人捕获他们自己的异常,他们通过回调方法返回给他们的主管.主管可以重新启动工作人员或采取其他行动.主机通过命令契约控制主管,命令契约指示他们启动和停止工作并返回数据.
我的主机应用程序是Windows服务.由于所有常见原因(包括错误!),工作线程抛出异常,但主机应用程序从未在我们的任何安装中崩溃.由于调试服务不方便,addin允许我构建使用相同合同的测试应用程序,并进一步保证我正在测试我部署的内容.
Addins也可以公开UI元素.这对我非常有帮助,因为我需要使用主机服务部署控制器应用程序,因为服务没有UI.每个插件都包含自己的控制器接口.控制器应用程序本身非常简单 – 它加载插件并显示其UI元素.这允许我发布带有更新接口的更新插件,而不必发送新控制器.
即使控制器和主机服务使用相同的插件,它们也不会互相踩踏;事实上,他们甚至不知道另一个应用程序正在使用相同的插件.控制器和主机通过共享数据库相互通信,但您也可以使用其他跨应用程序机制,如MSMQ.在下一个版本中,主机将是一个WCF服务,后端有插件,Web服务用于控制.
这有点啰嗦,但我想让你了解MAF的多样性.它并不像它最初看起来那么复杂,你可以用它构建坚如磐石的应用程序.