简体   繁体   中英

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

(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;
    }

}

The reason behind the duplicate exports is the fact that you are deriving your custom export metadata attribute from ExportAttribute . This means that when you decorate a class member with PluginAttribute , you do not need to add the ExportAttribute . MEF will look for attributes assignable to ExportAttribute and it will find one in your PluginAttribute .

For the other question regarding plug-in types, MEF allows for multiple exports on the same type. You can have one export of type IPlugin and another more specialized like you were doing 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 have different imports for each exported type. You can have an IEnumerable<IPlugin> import and then on another property a StrategyPlugin_Test1 import.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM