(1) Using the code below I get exactly 2 items in my containers of one and the same exported plugin and I wonder why:
(2) Additional question which I really cannot implement: How can I extend the framework to handle different plugin types (such as having several imports of different types, or one import that stores all plugins in a dynamic IEnumerable or so). I want to provide in my static wrapper class one generic method that returns the discovered plugin as a function of type and matching meta data.
The exported plugin (which resides in a separate dll and whose location is pointed to when the DirectoryCatalog
is built.
[Export(typeof(IPlugin))] //<---- If this line is commented out then only one item is imported (why?) [PluginAttribute(typeof(StrategyPlugin_Test1), "StrategyPlugin", "Plugin1")] public class StrategyPlugin_Test1 : IPlugin { public void DoSomething() { Console.WriteLine("I do something"); } }
The following code defines the strongly typed meta data and imports as well as a static class that performs the MEF functions and is supposed to hold the discovered plugins:
[MetadataAttribute] [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] public class PluginAttribute : ExportAttribute { public Type PluginType { get; set; } public string PluginGroupName { get; set; } public string PluginName { get; set; } public PluginAttribute(Type pluginType, string pluginGroupName, string pluginName) : base(typeof(IPlugin)) { PluginType = pluginType; PluginGroupName = pluginGroupName; PluginName = pluginName; } } public interface IPluginAttribute { Type PluginType { get; } string PluginGroupName { get; } string PluginName { get; } } public interface IPlugin { void DoSomething(); } public class PluginDefinition { [ImportMany(typeof(IPlugin))] public IEnumerable<Lazy<IPlugin, IPluginAttribute>> Plugins { get; set; } public PluginDefinition() { } }
Here the static class that wraps some of the core MEF stuff:
public static class PluginManager { private static PluginDefinition PluginDefinitions { get; set; } static PluginManager() {} public static void Configure(PluginDefinition pluginDefinitions, IEnumerable<string> pluginDirectories) { AggregateCatalog aggregateCatalog = new AggregateCatalog(new DirectoryCatalog(pluginDirectories.FirstOrDefault())); CompositionContainer container = new CompositionContainer(aggregateCatalog); container.ComposeParts(pluginDefinitions); //store plugin definition PluginDefinitions = pluginDefinitions; } public static T GetPlugin<T>(string pluginName, string pluginGroupName) where T : class { //how to implement this given type of T could be any of the plugin types ... //...provided for in an extended PluginDefinition class? return null; } }