我试图将.NET框架应用程序的集合移植到.NET Core,并且作为此过程的一部分,我需要从使用MEF1切换到MEF2。我在解决与MEF2有关的问题时遇到了很多困难(虽然我发现this post真的很有帮助),但是最近我偶然发现了其中一个人的背后原因。为什么MEF2不会将元数据属性应用于所有零件导出?
特别是,我有许多类使用自定义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
是d efined如下:
[MetadataAttribute, AttributeUsage(AttributeTargets.Class)]
public class TargetDeviceAttribute : ExportAttribute, IDeviceSpecific
{
public TargetDeviceAttribute(string deviceId)
{
this.DeviceId = deviceId;
}
public string DeviceId { get; private set; }
}
我发现发生的事情是,部分RelaySystemClientRequestProcessor
有两个出口对应:IClientRequestProcessor<RelaySystemModel>
,这是我很感兴趣的出口和接口我尝试导入带有的部分和RelaySystemClientRequestProcessor
。但是,“DeviceId”元数据仅与相关联,而不是前者,这没有帮助。
有几种方法,我认为这是可以解决的,虽然我还没有完全测试:
应用属性
ExportMetadata("DeviceId", "<<foo>>")
我所有的出口部分。更改
TargetDeviceAttribute
以使用构造函数public TargetDeviceAttribute(string deviceId, Type exportType) : base(exportType)
。
我不赞成这些解决方案;如果我想更改元数据密钥,前者会有问题,并且两者都会涉及更改我导出所有零件的方式。
我想知道的是,如果MEF2提供了一种导出MEF1中的元数据的方法:创建自定义元数据属性并使其适用于全部与零件关联的导出。这可能吗?