MEF, why are duplicates of the same exported plugin created?

(1) Using the code below, I get exactly 2 elements in my containers of the same exported plugin, and I wonder why:

(2) An additional question that I really can’t implement: how can I extend the framework to handle different types of plugins (for example, have several import types or one import that stores all plugins in dynamic IEnumerable or so on). I want to provide in my static wrapper class one common method that returns the detected plugin as a function of type and metadata matching.

Exported plugin (which is in a separate dll and which indicates when DirectoryCatalog 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 strongly typed metadata and imports, as well as a static class that performs MEF functions and must contain detected 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's a static class that wraps part of the core MEF material:

 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; } } 
+4
source share
1 answer

The reason for duplicating an export is because you get your own export metadata attribute from ExportAttribute . This means that when you decorate a member of the PluginAttribute class, you do not need to add ExportAttribute . MEF will look for attributes assigned by ExportAttribute , and it will find them in your PluginAttribute .

For another question about plug-in types, MEF allows you to use multiple instances of the same type. You can have one export of type IPlugin and even more specialized, as you did in your code:

 [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 

And then they have different import data for each exported type. You can import IEnumerable<IPlugin> , and then another property a StrategyPlugin_Test1 import.

+4
source

Source: https://habr.com/ru/post/1479500/


All Articles