Is MEF all or nothing?
I've had a few questions about MEF lately, but the big one - is it really all or nothing, as it seems?
My main application structure is just an application, a few shared libraries designed for single-user use, and a few different plugins (which may implement different interfaces). The application loads plugins and both applications and all plugins need to access the shared libraries.
My first exit at MEF was pretty successful, although I made some stupid mistakes along the way because I tried so many different things, I just got confused from time to time. But in the end, last night I got my little test application working with MEF, some shared libraries and one plugin.
I now turn to the target application I mentioned earlier. And these are a few parts of the plugins that worry a little.
My existing application already supports several plugins with different interfaces using Reflection. I need to be able to uniquely identify each plugin so that the user can select it and get the expected behavior opened by that plugin. The problem is I don't know how to do this yet ... but that is a topic for another question.
Ideally I could take my existing plugin loader and use it as is, and rely on MEF to resolve the shared library. The problem is that I cannot get MEF to load them (i.e. I get a Composition exception when calling ComposeParts ()) unless I also use MEF to load the plugin. And if I do, well ... then I need to know how to track them as they load so that the user can select one from the list of plugins.
What were you doing trying to mix and match these approaches?
a source to share
MEF is designed to allow you to load plugin assemblies easily. If you have control over plugins (I mean you can add MEF export attributes) then there is no need to keep your own plugin loader that uses reflection. MEF does it all for you.
Considering that "mixing and matching" MEF with other technologies is certainly possible. It looks like your problem is that if you are using your own plugin loader you are not adding those plugins to the MEF container. As a result, you get CompositionException
for parts that try to import the selected plugin.
To add a plugin that you loaded with your own code into the MEF container, you can use ComposeExportedValue
like this:
container.ComposeExportedValue<IPlugin>(selectedPlugin);
edit: I see what you mean by "all or nothing" now. Your problem is that in order to import parts using MEF, you also need to build an object using MEF. This problem then cascades to the object that usually creates that object, etc. Down to the root of the application.
To avoid this all-or-nothing effect, you can compromise by opening the MEF container as a global variable (that is, a static field). This way classes can access the MEF container and pull the export out of it, for example. calling Program.Container.GetExportedValue<MyDependency>()
in the constructor.
edit2 . If you have an object that was not created by MEF, there are two ways to add it to the container.
First, call container.ComposeExportedValue<IMyContractType>(myObject);
.
The second is to return the object to the getter property, and then mark the property itself with the [Export (typeof (SomeType))] attribute.
a source to share