使用MEF在运行时加载插件

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

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

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

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

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

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

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

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

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

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

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