Strange MEF SmartAssembly behavior
JohnRedGater
Posts: 17
I'm using MEF to find and load a plugin from the main directory. In the debug mode, which isn't obfuscated, the composition fails because it can't find any plugins in the directory and throws an error. This is expected behavior. In the release mode, which IS obfuscated, however, the composition doesn't throw any errors and proceeds leaving a null reference for the Import property. Subsequent calls get a null exception when they try to access the property. This is odd behavior; MEF should at least fail in somewhere in the composition process. Here's my code:
[Import(typeof(IPlugin))]
public IPlugin Plugin
{
get;
set;
}
public FindPlugins(string directory)
{
// should throw a composition exception
if (String.IsNullOrEmpty(directory))
directory = DirectoryOfExecutingAssembly;
var catalog = new DirectoryCatalog(directory);
CompositionContainer container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
[Import(typeof(IPlugin))]
public IPlugin Plugin
{
get;
set;
}
public FindPlugins(string directory)
{
// should throw a composition exception
if (String.IsNullOrEmpty(directory))
directory = DirectoryOfExecutingAssembly;
var catalog = new DirectoryCatalog(directory);
CompositionContainer container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
Comments
If IPlugin is defined in another assembly, and you are obfuscating or pruning that assembly separately or merging it into the main assembly, you may be making the metadata for IPlugin inaccessable. I'd suggest excluding that type from obfuscation and pruning.
I don't know a lot about how MEF works internally, but it is probably designed to catch an exception when the requested type is unknown.
Here's the process according to my poor recall. Originally, I MERGED the interface assembly into the main assembly. This made the interface assembly invisible to the plugin. I then tried to EMBED the interface assembly into the main assembly. Although it found the plugin, it couldn't find the plugin's referenced assemblies which were merged into the main assembly. I tried several combinations and I couldn't get them to work.
After several different setup arrangements, I found that I had to embed the plugins references into to the main assembly but leave the interface outside of both assemblies. Magically, this works and the plugin is able to reference the assemblies in the main assembly. The resulting plugin is very small and references everything it needs from the main assembly. Ideally, I wish the assemblies were merged instead of embedded for better protection. Also, it would be nice to deploy two assemblies, main and plugin, instead of three: main, plugin, and interface.
Given the popularity of MEF, I would strongly advise that it is directly addressed in either the software or technical documentation. I more than happy to provide assistance in helping reproduce these issues.