2016-10-04 24 views
1

我試圖將.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」元數據僅與相關聯,而不是前者,這沒有幫助。

MEF2-exports

有幾種方法,我認爲這是可以解決的,雖然我還沒有完全測試:

  1. 應用屬性ExportMetadata("DeviceId", "<<foo>>")我所有的出口部分。

  2. 更改TargetDeviceAttribute以使用構造函數public TargetDeviceAttribute(string deviceId, Type exportType) : base(exportType)

我不贊成這些解決方案;如果我想更改元數據密鑰,前者會有問題,並且兩者都會涉及更改我導出所有零件的方式。

我想知道的是,如果MEF2提供了一種導出MEF1中的元數據的方法:創建自定義元數據屬性並使其適用於全部與零件關聯的導出。這可能嗎?

回答

0

原來我只是需要刪除6個字符。相反,從ExportAttribute使TargetDeviceAttribute繼承的,它應該只是從Attribute而不是繼承:

[MetadataAttribute, AttributeUsage(AttributeTargets.Class)] 
public class TargetDeviceAttribute : Attribute, IDeviceSpecific 
{ 
    public TargetDeviceAttribute(string deviceId) 
    { 
     this.DeviceId = deviceId; 
    } 

    public string DeviceId { get; private set; } 
} 

在更一般的情況下,這意味着可以與多種可能的類型相關聯,但任何元數據應當確保更好的靜態類型安全/我應該像下面這樣做ExportAttribute("foo", "bar")可維護性:

public interface IMetadataExtension 
{ 
    string Foo { get; } 
} 

public class MetadataExtension : IMetadataExtension 
{ 
    public string Foo { get; set; } 
} 

[MetadataAttribute] 
public class MetadataExtensionAttribute : Attribute, IMetadataExtension 
{ 
    public MetadataExtensionAttribute(string foo) 
    { 
     Foo = foo; 
    } 

    public string Foo { get; } 
} 

[Export] 
[MetadataExtension("bar")] 
public class SomeExport 
{ 

} 
相關問題