c# - 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 实例是在带有接口的基本文件中定义的,并且该实例似乎可以很好地共存。
解决方案
推荐阅读
- java - 应该在主线程之外调用 getExternalCacheDir() 吗?
- java - 单独的容器和 Shiro 会话?
- html - HTML5 输入模式要求第一个字符必须是正斜杠
- ios - AVAudioFile (Mac/iOS) : 将音频编码为恒定比特率 AAC
- python - 在 python 列表中分离和计算表情符号
- javascript - 标题太长 将菜单按钮滑动到卡片右侧
- c# - 使用 .Net Core 3.1 运行 XSLT 2.0
- sql - 使用 ssis 从 excel 加载数据时意外终止
- c# - 如何在 c# 的日期时间选择器中添加秒数?
- r - 评估另一个表中是否不存在某个值