且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用MEF在运行时加载插件

更新时间:2023-11-24 17:35:46

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

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



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


My application allows users to write plugins (implementing IPlugin) that they can instantiate at runtime. On startup a directory of plugin .dlls is parsed, registering all the available plugins information. At runtime a GUI is provided that lets users create instances of any of the plugins. This works fine.

But now I see MEF and hope I can do the same, but in a more elegant way codewise.

What I got working so far with MEF: on startup I am doing an import of all plugins in a directory (that export IPlugin) and read out the information like name, category, author, etc... These are encoded as exported metadata attributes to the plugin classes. The import is done lazyly so all the plugins are not instantiated on startup, which is important.

The problem is that now I don't see a way to elegantly instantiate a selected plugin at runtime given the additional complication that the plugins constructor is an importing constructor which is importing a reference to an IPluginHost (which it needs immediately to do some initialization).

Together with a plugininfo I save the respective Export in a dictionary during startup, so when the GUI asks to instantiate a plugin given a specific plugininfo I have access to the Export (where Export.Value is my actual IPlugin). But from there how can I create an instance of the plugin and have it composed with the IPluginHost?

I gather I should write my own ExportProvider that serves the IPluginHost whenever someone asks for it, but I don't have access to the assembly or the type of the specific plugin that would let me add it to a Catalog, add the catalog and ExportProvider to a container and call .ComposeParts on that container.

I hope I made my problem clear, if not, let me try a short version of the question: isn't it a standard usecase for MEF to have a program that lazy-loads plugins on startup to parse the available plugins infos and then at runtime create specific instances given specific plugininfos? would be great to get a codeoutline of the steps involved.

If I understand correctly, you are looking for a way to dynamically create multiple plugin instances, potentially of the same plugin.

You need to declare an import of the type ExportFactory<IPlugin,IPluginMetadata> and then select the correct factory based on the metadata. ExportFactory.CreateExport will take care of any imports required by the IPlugin instances, like the IPluginHost you mentioned.

Note that ExportFactory was only in the silverlight edition of MEF in earlier releases. To get it in the desktop edition, you currently need the latest version from codeplex (MEF 2 - Preview 1). There is also a known problem with importing ExportFactory via the constructor, so use a property.