2009-11-18 79 views
5

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

我的问题是关于如何处理该扩展点。我见过这样做,不同的方式,但我不知道每个人的优点和缺点,如果有更多更好的方式来做到这一点:

  • 活动:添加静态事件,所有的东西我们想让“可扩展”。例如,如果我想为User类添加自定义验证,则可以添加一个OnValidation静态事件处理程序,并在构建时从该插件向它添加事件。
  • 信息:有一个公共汽车和一条消息。插件可以订阅特定的消息,并在其他类发布该消息时进行操作。消息应该包含插件可以工作的上下文。在验证情况下,逻辑层将发布UserValidation消息,并且插件将在接收到消息时采取行动。
  • 接口:主机应用程序负责调用实现某些接口的所有插件,并为它们提供当前操作的上下文。在验证的情况下,插件可以使用Validate(对象上下文)方法实现IValidator或IUserValidator。

你曾经使用过某种暴露的方法吗?哪一个最适合你?

在您提出问题之前,我们的应用程序是一个可扩展的核心(用户,rola和内容管理),用于构建以客户端为中心的Web应用程序。构建在ASP.NET MVC上的所有东西。

回答

2

您的设计决策的一个关键是要分析并清楚了解插件将来自于彼此的不同之处。

E.g.当处理静态事件时,您可能必须将每个事件定义为某种形式的令牌,枚举,对象等。必须为每个插件定义一组新事件自然会违背整个设计,特别是在松散耦合和重用。

如果你的插件是非常不同的从具有在这种情况下,因为你的总线/通讯架构可能引起通信交换,该插件可以订阅域/类别你可能会受益。即一系列事件和消息可能处于某个感兴趣的领域。请注意,某个类别内的通信仍然可以使用静态事件,因此这两个替代方案并不相互排斥。

插件实现的直接接口在我的经验中是最为严格的插件体系结构。扩展插件接口通常意味着在插件和提供者处修改代码。您需要有一个可靠的通用界面,您知道您的应用程序可以长期存在。

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

通常我会说,协议是最难从一开始就正确设计的,因为您可能没有一个牢固的感觉来确定您可以绘制线条的一般或特定程度。

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

+0

接口可能是我的方法,虽然它取决于应用程序和它的插件需求。 但是这是一个非常干净的插件方法,并且也很容易从插件中分离出异常。 – 2009-11-18 12:53:23

0

我愿意跟观察者模式。从GOF:

定义对象间的一种一对多的依赖 这样,当一个 对象改变状态的所有其 家属得到通知并自动更新 。

也被称为发布 - 订阅我会建议它在您的示例中最接近地匹配案例二。

+0

恕我直言,观察员模式是从这个问题的一个层面。即他提出的所有替代方案都适合这种模式。当前的问题与观察者模式的具体实施决定有关。 – sharkin 2009-11-18 12:53:13

+0

在再次阅读和进一步消化时,我认为你可能是正确的R.A. – Martin 2009-11-18 14:11:44