一旦加载插件的问题得到解决(在 .NET 中通过 MEF 的情况下),下一步要解决的是与它们的通信。简单的方法是实现一个接口(interface),使用插件实现,但有时插件只需要扩展应用程序的工作方式,可能会有很多扩展点。
我的问题是关于如何处理这些扩展点。我已经看到了不同的方法,但我不确定每种方法的优缺点,以及是否有更多更好的方法来实现这一点:
您曾经使用过其中一种公开的方法吗?哪一个最适合您?
在您问之前,我们的应用程序是一个可扩展的核心(用户、角色和内容管理),可在此基础上构建我们客户特定的以内容为中心的 Web 应用程序。一切都建立在 ASP.NET MVC 之上。
最佳答案
您的设计决策的关键是分析并清楚地了解插件彼此之间的差异。
例如。在处理静态事件时,您可能必须将每个事件定义为某种形式的 token 、枚举、对象等。必须为每个插件定义一组新的事件自然不利于您的整个设计,特别是在松散耦合和重用。
如果您的插件非常不同,您可能会从总线/消息传递架构中受益,因为在这种情况下您可以引入插件可以订阅的通信交换的域/类别。 IE。一系列事件和消息可以在某个兴趣域中。请注意,某个类别内的通信仍然可以利用静态事件,因此这两种选择并不相互排斥。
根据我的经验,插件实现的直接接口(interface)是插件架构中最严格的方法。扩展插件接口(interface)通常意味着插件和提供者的代码修改。您需要有一个可靠的通用界面,您知道您的应用程序可以运行相当长的一段时间。
通过将设计分解为两个方面,您可能更容易处理设计 - 沟通 channel 和 协议(protocol) .静态事件处理是一个协议(protocol)问题,而总线消息传递和直接接口(interface)是一个 channel 问题。
一般来说,我会说协议(protocol)是最难从一开始就正确设计的,因为您可能对划定界限的一般性或具体性没有扎实的感觉。
编辑: Lars 在他的评论中提出了一个重要的观点 - 如果您的平台支持异常,您可以在使用直接接口(interface)时集中处理许多错误,从而使插件不必处理通用的错误并且可能超出其特定域(例如“插件加载错误”或“文件打开失败”)。但是,如果每次添加插件时都必须维护接口(interface),这些好处似乎会消失。最坏的情况是当接口(interface)开始变得不一致时,因为您从一开始就没有意识到它们应该支持什么。在已经构思出大量插件的情况下重构整个界面设计并不是一件容易的事。
关于.net - 扩展/插件通信架构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1755670/