首页 > 解决方案 > MEF ImportMany 接口的第一个实现屏蔽了任何后续实现

问题描述

我对 MEF 插件的概念验证应用程序有疑问。我有一个简单的类,它现在返回一种颜色,并且 exportmetadata 标记该颜色。但是,如果我将三个 dll 放入目录中,每个都有一个唯一的导出,ImportMany 最终会得到三个要加载的第一件事的副本,并且其他的都不存在。

public interface IColorMatch
{
    string ValidationMessage { get; }
}

public interface IColorMatchData
{
    string Color { get; }
}

和实现,每个都在一个单独的 dll 中

[Export(typeof(IColorMatch))]
[ExportMetadata("Color","RED")]
class RedColor : IColorMatch
{
    public string ValidationMessage
    {
        get
        {
            return "RED";
        }
    }
}

[Export(typeof(IColorMatch))]
[ExportMetadata("Color","BLUE")]
class BlueColor : IColorMatch
{
    public string ValidationMessage
    {
        get
        {
            return "BLUE";
        }
    }
}

最后是加载它的代码

[ImportMany]
IEnumerable<Lazy<IColorMatch, IColorMatchData>> Colors;

public void OnClick(object sender, RoutedEventArgs e)
{
    var catalog = new AggregateCatalog();
    catalog.Catalogs.Add(new DirectoryCatalog(AppContext.BaseDirectory));

    //Create the CompositionContainer with the parts in the catalog
    _container = new CompositionContainer(catalog,CompositionOptions.DisableSilentRejection);

    //Fill the imports of this object
    try
    {
        this._container.ComposeParts(this);
    }
    catch (CompositionException compositionException)
    {
        Console.WriteLine(compositionException.ToString());
    }

    //this is just for convenience while at a breakpoint  
    var debug = Colors.Select(x => x.Metadata.Color.ToLower());
    var list = Colors.Where(x => x.Metadata.Color.ToLower() == txtColor.Text.ToLower());
    if (list.Count() < 1)
    {
        list = Colors.Where(x => x.Metadata.Color == "Default");
    }
    foreach (Lazy<IColorMatch, IColorMatchData> item in list)
    {
        lstbox.Items.Add($"This was processed using code for the {item.Value.ValidationMessage}");
    }
}

最后的结果是,如果我在目录中只使用 red.dll 启动 UI,调试列表将只有条目“RED”和“Default”。如果目录中只有 blue.dll,则调试包含“Blue”和“Default”。如果目录中同时有 red.dll 和 blue.dll,则 debug 包含“RED”、“RED”和“Default”。

显然检测到了两个副本,为什么只加载第一个副本两次?Default 实例是在带有接口的基本文件中定义的,并且该实例似乎可以很好地共存。

标签: c#mef

解决方案


推荐阅读