使用MEF在运行时加载插件

时间:2010-07-19 22:04:59

标签: c# dynamic plugins mef

我的应用程序允许用户编写可在运行时实例化的插件(实现IPlugin)。在启动时,解析插件.dll的目录,注册所有可用的插件信息。在运行时,提供了一个GUI,允许用户创建任何插件的实例。这很好用。

但现在我看到了MEF,并希望我能做同样的事情,但是以更优雅的方式代码化。

到目前为止我使用MEF工作:在启动时我正在导入目录中的所有插件(导出IPlugin)并读出名称,类别,作者等信息...这些被编码为插件类的导出元数据属性。导入是懒惰的,因此所有插件都不会在启动时实例化,这很重要。

问题是现在我没有看到在运行时优雅地实例化所选插件的方法,因为插件构造函数是导入构造函数,导入对IPluginHost的引用的额外复杂性(它需要立即进行一些初始化)。

与plugininfo一起,我在启动期间将相应的Export保存在字典中,因此当GUI要求实例化给定特定插件信息的插件时,我可以访问Export(其中Export.Value是我的实际IPlugin)。但是从那里我如何创建插件的实例并将其与IPluginHost组合?

我收集我应该编写自己的ExportProvider,只要有人要求它就会为IPluginHost提供服务,但是我无法访问程序集或特定插件的类型,这些插件可以让我将它添加到目录中,添加catalog和ExportProvider到一个容器并在该容器上调用.ComposeParts。

我希望我能清楚地解决问题,如果没有,让我试试短版本的问题: 是不是MEF的标准用例有一个程序,在启动时延迟加载插件来解析可用的插件信息,然后在运行时创建给定特定plugininfos的特定实例?获得所涉及步骤的代码行是很好的。

2 个答案:

答案 0 :(得分:2)

如果我理解正确,您正在寻找一种方法来动态创建多个插件实例,可能是相同的插件。

您需要声明类型ExportFactory<IPlugin,IPluginMetadata>的导入,然后根据元数据选择正确的工厂。 ExportFactory.CreateExport会处理IPlugin个实例所需的任何导入,例如您提到的IPluginHost

请注意ExportFactory仅在早期版本的MEF银光版中。要在桌面版中获取它,您目前需要codeplex的最新版本(MEF 2 - 预览1)。通过构造函数导入ExportFactory也存在一个已知问题,因此请使用属性。

答案 1 :(得分:0)

你创建了CompositionContainer吗?您可以使用它来请求特定的插件类型并实例化它们。目录将让您在那里的一部分。您可以聚合多个目录(使用AggregateCatalog),然后将结果传递给CompositionContainer的构造函数。当您请求特定的IPlugin类型(只跟踪导出的类型)时,您可以要求CompositionContainer为您实例化插件,它将自动为您执行构造函数注入。