MEF,为什么创建了一个相同的导出插件的相同副本? [英] MEF, why are identical duplicates of one and the same exported plugin created?

查看:16
本文介绍了MEF,为什么创建了一个相同的导出插件的相同副本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(1) 使用下面的代码,我的容器中正好有 2 个项目,其中包含一个相同的导出插件,我想知道为什么:

(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) 我真的无法实现的附加问题:如何扩展框架以处理不同的插件类型(例如具有多个不同类型的导入,或者一个将所有插件存储在动态 IEnumerable 左右的导入).我想在我的静态包装器类中提供一个通用方法,该方法将发现的插件作为类型和匹配元数据的函数返回.

(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.

导出的插件(驻留在单独的 dll 中,并且在构建 DirectoryCatalog 时指向其位置.

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");
    }
}

以下代码定义了强类型元数据和导入,以及一个执行 MEF 功能并应该保存发现的插件的静态类:

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()
    {

    }
}

这里是封装了一些核心 MEF 内容的静态类:

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

}

推荐答案

重复导出背后的原因是您从 ExportAttribute.这意味着当您使用 PluginAttribute 修饰类成员时,您不需要添加 ExportAttribute.MEF 将寻找可分配给 ExportAttribute 的属性,它会在您的 PluginAttribute 中找到一个.

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.

关于插件类型的另一个问题,MEF 允许同一类型的多个导出.您可以有一个 IPlugin 类型的导出和另一个更专业的导出,就像您在代码中所做的那样:

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

然后为每种导出类型设置不同的导入.您可以导入 IEnumerable,然后在另一个属性上导入 StrategyPlugin_Test1.

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.

这篇关于MEF,为什么创建了一个相同的导出插件的相同副本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆