.net - 扩展/插件通信架构

标签 .net asp.net-mvc architecture plugins extensibility

一旦加载插件的问题得到解决(在 .NET 中通过 MEF 的情况下),下一步要解决的是与它们的通信。简单的方法是实现一个接口(interface),使用插件实现,但有时插件只需要扩展应用程序的工作方式,可能会有很多扩展点。

我的问题是关于如何处理这些扩展点。我已经看到了不同的方法,但我不确定每种方法的优缺点,以及是否有更多更好的方法来实现这一点:

  • 事件:将静态事件添加到我们想要“可扩展”的所有内容中。例如,如果我想为一个 User 类添加自定义验证,我可以添加一个 OnValidation 静态事件处理程序,并在构造它时从插件向它添加事件。
  • 消息:有总线和消息。该插件可以订阅特定消息并在其他一些类发布该消息时执行某些操作。该消息应包含插件可以工作的上下文。在验证的情况下,逻辑层会发布一条 UserValidation 消息,插件会在收到消息时采取行动。
  • 接口(interface):宿主应用程序负责调用所有实现特定接口(interface)的插件,并为它们提供当前操作的上下文。在验证的情况下,插件可以使用 Validate(object context) 方法实现 IValidator 或 IUserValidator。

  • 您曾经使用过其中一种公开的方法吗?哪一个最适合您?

    在您问之前,我们的应用程序是一个可扩展的核心(用户、角色和内容管理),可在此基础上构建我们客户特定的以内容为中心的 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/

    相关文章:

    c# - WriteableBitmap访问冲突问题

    c# - 为什么在使用 Rhino Mocks stub 函数时需要 Replay()?

    Html.Raw 改变整个页面的样式

    jquery - 如何在 ASP.NET MVC 中返回 JSON 格式的 500 错误?

    asp.net-mvc - 在 ASP.NET MVC 中使用 View 模型 + 数据模型来支持类型化 View ?

    architecture - 如何成为技术架构师?

    .net - 如果在 TabControl 或 Panel 中查找 Control,Form.Controls 将不返回任何内容

    c# - .NET Jquery 脚本错误

    ASP.NET MVC : Pass list of objects from Controller to View

    C++ 从不透明指针传递私有(private)数据