views:

257

answers:

2

helos,

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 infos. at runtime a GUI is provided that lets users create instances of any of the plugins. this works.

but now i see MEF and hope i can do the same more elegant, 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 their informations (like name, category, author,...) which are encoded as exported metadata attributes to the pluginclasses. the import is done lazy so all the plugins are not actually instantiated on startup, which is important.

the problem is now that 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 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.

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.

+1  A: 

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.

Wim Coenen
@Wim, have you had success with MEF 2 Preview 1, I get assembly conflicts with the .NET 4.0 System.Components.Composition one! ExportFactory is specifically what I wanted it for!
Ray Hayes
sorry for late answer. i was able to solve my problem with the ExportFactory as explained. using .net 3.5 though.
joreg
A: 

Have you created a CompositionContainer yet? You can use it to request particular plugin types and get them instantiated. The catalogs will get you part of the way there. You can aggregate multiple catalogs (using the AggregateCatalog) then pass the result to the constructor of the CompositionContainer. When you request your specific IPlugin Type (just keep track of the Type of the export) and you can ask the CompositionContainer to instantiate the plugin for you and it will do the constructor injection for you automatically.

Garo Yeriazarian