.NET中的插件式架构

我正在尝试实现类似应用程序的插件。 我知道已有几种解决方案,但这只是该概念的certificate,仅此而已。 这个想法是默认情况下使应用程序主应用程序几乎没有function,然后让插件相互了解,让它们实现所有需要的function。

出现了几个问题:

  1. 我希望运行时的插件通过我的应用程序了解彼此。 这并不意味着在代码时他们无法引用其他插件的程序集,所以他们可以使用它的接口,只有插件function初始化应该始终通过我的主应用程序。 例如:如果我同时加载了插件X和Y,并且Y想要使用X的function,它应该通过我的应用程序“注册”它的兴趣来使用它的function。 我必须在我的应用程序中有一种“字典”,我存储所有加载的插件。 注册我的应用程序后,插件Y将获得对X的引用,以便它可以使用它。 这是一个好方法吗?
  2. 在编写使用X的插件Y时,我需要引用X的程序集,因此我可以针对其接口进行编程。 这有版本控制的问题。 如果我对插件X的过时版本编码我的插件Y怎么办? 我应该总是使用所有组件都在的“中央”位置,总是有最新版本的组件吗?

有没有专门处理这些.NET设计的书?

谢谢

编辑:我认为人们正在偏离我提出的两个问题。 我可以看看MEF和#develop,但我想得到具体的问题答案。

查看System.AddIn命名空间。 它比MEF略低,因此应该为您提供“自己实施”的体验。

我建议调查MEF 。 这是一种在.NET中进行插件的新方法。 例如,这是为VS2010做新插件的推荐方法。 我自己没有用过它,但是我对它的看法看起来很棒。 添加这个作为别人刺激的答案:)

有一本关于构建您正在寻找的内容的好书:解析C#应用程序:在SharpDevelop内部。 这是一个链接: http : //www.icsharpcode.net/OpenSource/SD/InsideSharpDevelop.aspx

SharpDevelop应用程序是完全基于插件的,本书讨论了它们如何构建它,它们面临的陷阱以及它们如何克服它。 这本书可以从网站免费获得,或者你也可以购买。

一旦我使用这个例子完成它。 我喜欢它,但几年前,我认为现在可能有更好的解决方案。 只要我记得基本的想法是你的程序中有抽象类,你的插件inheritance该类并编译为DLL …或类似的东西使用接口。 无论如何,这种方法对我来说非常有用。 后来我添加了一个filesystemwatcher,因此它可以在运行时加载这些DLL插件。

加载程序集

获取程序集公开的类型

关于您暴露的两个具体问题:

1)我不确定你想要实现什么,但我的猜测是你想要延迟初始化function,并且可能延迟加载加载项。 如果这是目标,那么你提出的建议可能会奏效。 所以它可以像这样工作:

  • Y插件提供了它需要使用的function列表(例如,可以通过特定的接口实现或通过xml清单来完成)。
  • X加载项实现了一个API,允许使用Initialize(featureId)等方法初始化一个function。
  • 主机应用程序获取Y所需的function列表,加载/初始化X插件,并为每个function调用Initialize
  • 宿主应用程序还提供了一个GetFeature()方法,Y可用于获取对“特征”对象的引用,该对象将在X中实现。

但是,如果插件Y可以直接访问X API,我认为没有必要拥有用于注册function的所有基础结构。 Y可以直接使用X API来访问Xfunction,Y会在需要时负责延迟初始化每个function。 例如,Y可以调用SomeXFeature.DoSomething(),该类的实现将在第一次使用时初始化该function。

2)如果组件的API发生变化,任何取决于它的组件都可能会中断。 插件只是依赖于其他组件的组件,因此它们也会破坏。 您可以采取以下措施来缓解此问题。

  • 为每个插件分配版本号。 这可能只是assembly版本。
  • 加载插件时,请确保可以正确地满足所有依赖项(即,它所依赖的所有插件必须存在且具有所需的版本)。 如果无法满足依赖性,则拒绝加载插件。
  • 实现一个插件管理工具,用于所有插件安装/卸载操作。 在尝试安装具有不满足的依赖项的插件时,或者在尝试卸载其他插件所依赖的插件时,管理器可以检查依赖关系并报告错误。

Mono.Addins框架使用类似的解决方案。 在Mono.Addins中,每个加载项都有一个版本号和一个依赖于它的加载项/版本列表。 加载加载项时,加载项引擎可确保加载具有正确版本的所有相关加载项。 它还提供了API和命令行工具,用于管理加载项的安装。