【发布时间】:2016-10-04 08:45:10
【问题描述】:
我正在尝试将一组基于 .NET Framework 的应用程序移植到 .NET Core,作为此过程的一部分,我需要从使用 MEF1 切换到 MEF2。我一直很难解决与 MEF2 相关的问题(尽管我发现 this post 真的很有帮助),但我最近偶然发现了其中一个问题背后的原因。
特别是,我有许多使用自定义ExportAttribute 导出元数据的类,我想将它们全部导入另一个类并根据此元数据过滤它们。这在 MEF1 中一切正常,但在 MEF2 中,我遇到了诸如“x 的导出元数据丢失且未提供默认值”等问题。
更具体地说,我将导出的类注释如下:
[Export(typeof(IClientRequestProcessor<RelaySystemModel>))]
[TargetDevice("<<Foo>>")]
internal class RelaySystemClientRequestProcessor : IClientRequestProcessor<RelaySystemModel>
{
}
然后在其他地方,我会尝试像这样导入它们:
[ImportMany]
public IEnumerable<ExportFactory<IClientRequestProcessor<RelaySystemModel>, DeviceSpecific>> RelayRequestProcessors { private get; set; }
然后,在满足导入的情况下,尝试按元数据过滤它们:
private static IEnumerable<ExportFactory<T, DeviceSpecific>> FilterForFoo<T>(IEnumerable<ExportFactory<T, DeviceSpecific>> items)
{
return from it in items where it.Metadata.DeviceId == "<<Foo>>" select it;
}
其中TargetDeviceAttribute定义如下:
[MetadataAttribute, AttributeUsage(AttributeTargets.Class)]
public class TargetDeviceAttribute : ExportAttribute, IDeviceSpecific
{
public TargetDeviceAttribute(string deviceId)
{
this.DeviceId = deviceId;
}
public string DeviceId { get; private set; }
}
我发现发生的事情是 part RelaySystemClientRequestProcessor 对应于两个 exports:IClientRequestProcessor<RelaySystemModel>,这是我感兴趣的导出和我尝试导入部件的界面和RelaySystemClientRequestProcessor。但是,“DeviceId”元数据仅与后者关联,而不与前者关联,这没有帮助。
虽然我还没有完全测试过,但我相信有几种方法可以解决这个问题:
将属性
ExportMetadata("DeviceId", "<<foo>>")应用于我所有导出的部件。将
TargetDeviceAttribute更改为使用构造函数public TargetDeviceAttribute(string deviceId, Type exportType) : base(exportType)。
我不赞成这些解决方案;如果我想更改元数据密钥,前者会出现问题,并且两者都涉及更改我导出所有部分的方式。
我想知道的是,MEF2 是否提供了一种像 MEF1 那样导出元数据的方法:通过创建自定义元数据属性并将该元数据应用于与部件关联的 所有 导出。这可能吗?
【问题讨论】: