2010-05-07 97 views
9

我想要实现插件式应用程序。我知道现在已经有几种解决方案,但这只是对这个概念的证明,没有其他。这个想法是让应用程序的主应用程序在默认情况下几乎没有特色,然后让插件相互了解,让它们实现所有需要的功能。.NET中的插件式体系结构

几个问题就出来了:

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

有没有偶然的机会找到那些专门针对这些.NET设计的书?

感谢

编辑:我认为人们漂离我做了2个问题了。我可以看一下MEF和#develop,但我想详细解答我提出的问题。

+8

我建议寻找MEF,这是全新的,但看起来很有希望。 – 2010-05-07 21:50:22

+2

@马特 - 想你应该把这个作为一个答案 - 这正是我要说 – 2010-05-07 21:51:13

+1

我已经听到了MEF的,但是作为OP说,我的想法是不使用已建成的框架,但落实它自己。它不需要非常复杂的东西。 – 2010-05-07 21:52:02

回答

3

调查System.AddIn命名空间。它比MEF稍低一点,所以应该给你“正在实施它”的经验,你正在寻找。

+1

有用的链接:[MEF vs AddIn](http://stackoverflow.com/questions/835182/choosing-between-mef-and-maf-system-addin)和[MSDN System.AddIn](http:// msdn。 microsoft.com/en-us/library/gg145020(v=vs.100).aspx) – 2012-10-12 15:43:49

1

一旦我完成它使用this example。我喜欢它,但几年前,我想现在可能会有更好的解决方案。只要我记得基本的想法是在你的程序中有抽象类,并且你的插件继承那个类并编译为DLL ......或者使用Interfaces类似的东西。无论如何,这种方法对我很好。后来我添加了一个filesystemwatcher,这样它可以在运行时加载这些DLL插件。

To load an Assembly

To get the types the assembly exposes

+1

正是我要说的。添加了一些感兴趣的MSDN页面的链接。 – Skizz 2010-05-07 22:25:35

+0

是的,但这是一个简单的例子。只是基本的反思和简单的OO设计。 – 2010-05-08 03:25:39

+0

是的,这是......我唯一的理由是因为它能够解决你上面指定的问题......当然,你需要编写复杂的插件管理器。如果你正在寻找一些开箱即用的东西,那么就像MEF一样,像所有人一样建议......它似乎非常强大。 – m0s 2010-05-08 06:38:49

2

有一本好书,打造你在找什么:剖析C#应用程序:内部SharpDevelop的。这里有一个链接:http://www.icsharpcode.net/OpenSource/SD/InsideSharpDevelop.aspx

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

6

我建议您考虑一下MEF。这是一种在.NET中执行插件的新方法。例如,这是推荐用于VS2010的新插件的方式。我自己并没有使用它,但是我对它的看法很好看。添加此为别人:)

+0

请参阅http://stackoverflow.com/questions/835182/choosing-between-mef-and-maf-system-addin。 MEF不是创建加载项的框架。 – cdiggins 2013-01-06 23:17:05

0

关于你暴露了两个具体问题的敦促下一个答案:

1)我不知道什么是你想实现的,但我的猜测是,你想拥有功能的延迟初始化,以及延迟加载插件。如果这是目标,那么你提出的建议可能会起作用。所以它可以像这样工作:

  • Y插件提供了它需要使用的功能列表(可以通过特定的接口实现或通过xml清单来完成)。
  • 的X外接实现其允许初始化的特征,与像初始化(FEATUREID)的方法的API。
  • 主机应用程序获取由Y所需要的功能列表,加载/初始化X插件,并呼吁初始化每个功能。
  • 主机应用程序还提供了一种GetFeature()方法其中Y可以用它来得到一个“功能”对象,这将在X.实施

但是参考,如果插件Y具有直接访问X API,我认为没有必要拥有所有用于注册功能的基础架构。 Y可以通过直接使用X API来访问X特性,并且在需要时Y会照顾每个特性的懒化初始化。例如,Y可以调用SomeXFeature.DoSomething(),并且该类的实现将在首次使用该特性时初始化该特性。

2)如的组件改变的API,任何组件取决于它可能会断裂。插件只是依赖于其他程序集的程序集,所以它们也会中断。以下是一些可以减轻这个问题的方法。

  • 分配一个版本号的每个插件。这可能只是程序集版本。
  • 当加载插件,确保所有的依赖性可适当满足(即,它依赖必须存在和所需版本的所有插件)。拒绝加载插件,如果不能满足依赖关系。
  • 实现插件管理工具,用于所有插件安装/卸载操作。当试图安装不满意的依赖性插件时,或试图卸载其他插件所依赖的插件时,管理器可以检查依赖关系并报告错误。

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