【问题标题】:Architecture for extension/plugin communication扩展/插件通信架构
【发布时间】:2010-12-17 20:38:45
【问题描述】:

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

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

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

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

在您问之前,我们的应用程序是一个可扩展的核心(用户、角色和内容管理),可在此基础上构建以客户特定内容为中心的 Web 应用程序。一切都建立在 ASP.NET MVC 之上。

【问题讨论】:

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


    【解决方案1】:

    您的设计决策的关键是分析并清楚地了解插件之间的差异。

    例如在处理静态事件时,您可能必须将每个事件定义为某种形式的令牌、枚举、对象等。必须为每个插件定义一组新的事件自然不利于您的整个设计,特别是在松散耦合和重复使用。

    如果您的插件非常不同,您可能会从总线/消息传递架构中受益,因为在这种情况下,您可以引入插件可以订阅的通信交换的域/类别。 IE。一系列事件和消息可以在某个兴趣域中。请注意,某个类别内的通信仍然可以利用静态事件,因此这两种选择并不相互排斥。

    插件实现的直接接口在我的经验中是插件架构中最严格的方法。扩展插件接口通常意味着插件和提供者的代码修改。您需要有一个可靠的通用界面,您知道您的应用程序可以运行相当长的一段时间。

    将设计分解为沟通渠道协议两个方面,您可能会更容易处理设计。静态事件处理是一个协议问题,而总线消息传递和直接接口是一个通道问题。

    一般来说,我会说协议是最难从一开始就正确设计的,因为您可能对划定界限的一般性或具体性没有扎实的感觉。

    编辑: Lars 在他的评论中提出了一个重要的观点 - 如果您的平台支持异常,您可以在使用直接接口时集中处理大量错误,从而使插件不必处理那些是通用的,可能超出了它们的特定域(例如“插件加载错误”或“文件打开失败”)。但是,如果每次添加插件时都必须维护接口,这些好处似乎会消失。最坏的情况是当接口开始变得不一致时,因为您从一开始就没有意识到它们应该支持什么。在已经构思出大量插件的情况下重构整个界面设计并非易事。

    【讨论】:

    • 接口可能是我的方法,尽管它取决于应用程序及其插件需求。但这是一种非常干净的插件方式,而且也很容易从插件中隔离异常。
    【解决方案2】:

    我会选择 Observer 模式。来自GOF:

    定义一个一对多的依赖 物体之间,这样当一个 对象更改其所有状态 家属被通知和更新 自动。

    也称为发布-订阅,我建议它与您的示例中的情况二最匹配。

    【讨论】:

    • 恕我直言,观察者模式比这个问题更上一层楼。 IE。他提出的所有替代方案都适合这种模式。手头的问题与观察者模式的实现特定决策有关。
    • 再次阅读并进一步消化,我认为您可能是正确的 R.A.
    猜你喜欢
    • 1970-01-01
    • 2020-11-07
    • 1970-01-01
    • 1970-01-01
    • 2017-08-28
    • 2012-03-12
    • 2010-09-24
    • 2022-12-19
    • 1970-01-01
    相关资源
    最近更新 更多