我試圖將.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中的元數據的方法:創建自定義元數據屬性並使其適用於全部與零件關聯的導出。這可能嗎?