【问题标题】:Best c# archeticture / pattern for communicating between separate plugins of application [closed]用于在应用程序的单独插件之间进行通信的最佳 C# 架构/模式 [关闭]
【发布时间】:2013-03-11 22:38:11
【问题描述】:

我目前正在从头开始设计一个系统,我们遇到了一个架构设计方案,我不确定最好的解决方法 - 但我相信其他人已经解决了,而且可能有甚至是它的模式。

到目前为止的故事:

我们有一个多租户网站,我们在其中实现各种功能作为插件,我们的客户将选择他们希望在他们的应用程序中使用的插件。每个插件都可以有各种用户可以添加到页面的“小部件”。 (例如,类似于 Android 应用程序通常带有可以添加到主屏幕的小部件的想法)。

插件可以依赖于其他插件来启用(例如电子商务插件需要支付插件)。插件也可以使用其他插件来增强其功能(例如,博客插件可以选择使用评论插件,也可以将评论与电子商务产品一起使用)。

尽可能地,我们希望每个插件都是独立的,具有非常简洁的公共接口。我们相信这种关注点分离将为我们提供整个系统的最佳长期灵活性和可维护性。

问题:

当我们开始布局我们目前知道的所有插件(更不用说未来的需求),以及它们与其他插件的依赖关系和可能的关系时 - 它开始与疯狂的蜘蛛网非常相似。我们也开始看到一些循环引用发生。

例如,导航插件需要知道网站上有哪些页面。但您也可以将导航小部件添加到页面。

部分/潜在的解决方案:

我们认为每个插件都应该与其他插件完全分开,但会通过消息从其他插件获取信息并与之通信。这些消息可以分为两种基本类型

  • 从另一个插件请求信息(请求/响应消息)
  • 事件通知(事件消息)

这两种消息类型都是非常简单的 DTO 类型类 - 它们不应该包含任何业务逻辑 - 只是一些其他服务处理请求并提供响应所需的信息。

我已经模拟了几个插件的一个非常简化的版本,我们看到它们与其他插件交互的解决方案是:http://screencast.com/t/Mdb9wUmMF

在此图中,Navigation、Page、Search 和 Other 插件不会相互了解任何信息。但他们会知道可用的消息和 ProcessMessages 接口。

例如请求/响应消息

Navigation 和其他插件会知道,如果它向 ProcessMessages 发送 GetPagesRequest,它将返回一个 PagesResponse,其中包含他们需要的所有信息。 (Nav/Other 插件需要立即响应 GetPagesRequest。)

导航和其他插件对页面插件一无所知。

请求/响应消息要求

引发请求消息的插件总是(通常?)期望立即收到响应消息。

只有 1 个服务知道如何处理请求消息,并提供将传递回调用插件的响应消息。

例如事件消息

当用户在页面插件中更新页面的 url 时,插件会向 ProcessMessages 发送 PageUrlUpdated 消息。 Navigation 和 Other 插件将使用 PageUrlUpdated 消息并执行它需要的任何操作。

事件消息要求

引发事件的插件从不期待响应。 0-许多插件可能会使用给定的消息。

(技术说明:对于事件消息,我们将把它们发送到 MassTransit 和 RabbitMQ - 然后每条消息有 1-n 个消费者)

问题

  1. 从我们制作的一些草图来看,上述想法似乎可行,并且系统不同元素之间的相互依赖性要少得多。但我不知道设计模式或架构结构的名称——或者我是否走错了路。我希望有人能给我指出正确的解决方案——一些好的文档和例子会很棒。 (尽量避免重新发明轮子 - 现有模式可能会更加稳健和成功)

  2. 对于请求消息,我们设想了某种从请求消息到将处理该消息的具体插件/服务的 StructureMap 映射。再说一次 - 我确信这个问题之前已经解决了,并且有一个模式,或者我们完全走错了路,有更好的解决方案。

非常感谢任何帮助和想法 萨安

PS - 我也会在一个具有一些基本属性的公共项目中拥有一个 IWidget - 所以页面插件可以请求所有实现 IWidget 的类添加到页面中

【问题讨论】:

  • 听起来 MEF 是一个不错的起点——看看msdn.microsoft.com/en-us/library/dd460648.aspx
  • 托管可扩展性框架足够强大,可以处理这种架构。本质上,插件会改变您的默认策略。 MEF 还提供属性和构造函数注入,因此您可以实例化一个插件并注入另一个插件。
  • 分而治之。针对特定问题提出更小、更明确的问题,例如how can I allow non-related classes consume information frome each othershow can a plugin invoke another plugin without create hard coupling between the plugins
  • 对于其他查看此问题的人。我最终发现上面的问题和图表描述了中介者模式。

标签: c# design-patterns plugins architecture


【解决方案1】:

您的问题有很多不同的方法;但我可能会建议面向服务的架构。主要是因为它可以以非常快速和敏捷的方式适应业务。这种架构提供了许多好处:

  • 轻量级
  • 敏捷
  • 代码可重用性

但它确实带来了一系列可能需要克服的障碍,例如:

  • 互操作性
  • 安全性
  • 性能
  • 坚持

因此,实施其中一些解决方案可能会缓解此类问题。但是,这需要您对此事有一定的了解。由于这种架构是敏捷的,但一切都暴露在一定程度上。此外,多个实例被实例化怎么办?

这些都是您必须识别的潜在项目。

我个人会做的是找到业务的真正核心——而不是项目;但业务。然后确定哪种方法最能完成该任务。这将是一个持续存在的模式,因为它是业务核心。

在这个问题上我强烈推荐的一些事情是:

还有很多其他可行的书籍,但我觉得其中一些很有帮助。当他们将涉及的大量设计讨论推向高潮时:

  • 延迟加载
  • 工作单元
  • 存储库
  • 依赖注入
  • 模型可扩展性框架
  • 还有更多...

这将填补几个空白;但我怎么强调都不过分。 没有比其他技术更好的技术,它们都有优点和缺点。但是,最能实现您的业务目标的技术是理想的选择

我理解您需要回复来帮助您,但请记住:

         Ask not the Elves for counsel, as they both say yes and no.

仅仅因为我们不了解您的项目或业务,这些目标就会严重影响您的决定。这些是只有你会知道的事情。正如我所说的,我们不知道你会想考虑什么:

  • 公司目标
  • 可维护性
  • 公司增长预测
  • 公司范式的可能转变。

还有更多,但您必须考虑其中一些变量,以使应用程序的衰减率在一段时间内保持停滞。所以应用程序的生命周期会持续相当长的一段时间。

希望这会有所帮助,但那是我的两分钱。

【讨论】:

  • -1 您列出了有用的一般架构链接,但并没有真正回答问题。
  • @jgauffin 这些书籍对于学习几种类型系统的几种模式的顶点都是可行的。它将为他提供正确评估所需内容以及可能适合他的架构所需的工具。你读过那些吗?很抱歉您有这种感觉,但他们非常详细地介绍了如何解决此类问题。
  • 谢谢。关于企业架构的一个很好的答案,以及非常有用的链接。 +1。
猜你喜欢
  • 1970-01-01
  • 2015-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-17
  • 1970-01-01
  • 1970-01-01
  • 2018-02-10
相关资源
最近更新 更多