I am trying to use MEF (The version that is built in mono) for a simple pluginsystem to extend my application. I followed various tutorials that are running well with Microsofts .NET framework under windows, but (same code) failing under linux(kernel 3.7.3 - gentoo) with mono-2.10.9.
I created an interface, that all Exports (my extensions) have to reference to in an external assembly:
namespace PlugInInterface {
[InheritedExport]
public interface IPlugIn {
void Execute();
}
}
Then I created a Hostapplication (a ConsoleApplication) that also references to the PluginInterface:
namespace Host {
class MainClass {
private static PluginHost plugins;
public static void Main(string[] args) {
plugins = new PluginHost();
foreach(IPlugIn plugin in plugins.plugins) {
plugin.Execute();
}
}
}
class PluginHost{
[ImportMany(typeof(IPlugIn))]
public List<IPlugIn> plugins = new List<IPlugIn>();
public PluginHost() {
var catalog = new DirectoryCatalog("PlugIns");
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
}
}
And one Extension that gets compiled in the "PlugIns" subfolder of the Debug directory, where the host-application is placed:
namespace TestPlugin1 {
[Export(typeof(IPlugIn))]
public class TestPlugin1 : IPlugIn {
public void Execute() {
Console.WriteLine("Hello, my Name is TestPlugin_Implementation1");
}
}
}
The DirectoryCatalog loads the PlugIn's file ("./PlugIns/TestPlugin1.dll") but it does not recognize it as an Export (a "Part") so the plugins
list remains empty.
It works, if I put the PluginFile in the application's workingdirectory and change the DirectoryList to:
var catalog = new DirectoryCatalog("");
If I run the compiled version that has been compiled from the .NET compiler with mono, the PlugIn is loaded twice.
I tried to replace the DirectoryCatalog manually by loading the PlugIn-files with System.Reflection.Assembly.LoadFile(...);
and then using AssemblyCatalogs to load all found assemblies:
class PluginHost{
[ImportMany(typeof(IPlugIn))]
public List<IPlugIn> plugins = new List<IPlugIn>();
public PluginHost() {
List<AssemblyCatalog> catalogs = new List<AssemblyCatalog>();
foreach(string plfile in Directory.GetFiles("PlugIns", "*.dll", SearchOption.AllDirectories)) {
catalogs.Add(new AssemblyCatalog(System.Reflection.Assembly.LoadFile(plfile)));
}
var container = new CompositionContainer(new AggregateCatalog(catalogs));
container.ComposeParts(this);
}
}
This works, but the same as with the compiled .NET executable: the PlugIn loads twice.
Is this a bug of mono and it's implementation of MEF, or am I doing something wrong?