2010-08-11 56 views
7

我已經成功使用MEF來獲取導出的類實例。但是,我遇到了一種情況,我需要枚舉一組導出的派生類而不實例化它們。我查閱了CompositionContainer的文檔,它似乎只能返回對象實例。是否可以使用MEF來獲取標記爲[Export]的類的System.Type?

我知道我可以在每個派生類中有一個靜態Type字段並將其導出,或者做我自己的反射,但是我想知道是否有內置的方式來標記具有[Export]屬性的類,然後列舉他們的System.Type

回答

4

正如萊皮說的那樣,沒有內建的方法可以做到這一點。這是設計。不一定是導出和類型之間的一對一映射(例如,任何數量的部件都可以具有String類型的屬性導出)。另外,對於不同的編程模型,該部分可能來自配置文件或動態編程語言,因此嘗試獲取與其關聯的CLR類型可能沒有多大意義。

+0

這幾乎是我得出的結論。謝謝。 – Trillian 2010-08-12 00:27:13

1

對此使用反射有什麼問題嗎?

如果沒有,這是我的答案:)

編輯:

沒有內置的方式來獲得在裝配的所有類型有特定屬性。

+0

不,使用反射沒有什麼「錯誤」,但發現[導出]'編輯類型是MEF的重要組成部分,我認爲它會提供獲取該信息的支持。 – Trillian 2010-08-11 17:03:43

4

根據您嘗試執行的操作的範圍,您可能還會使用API​​引入的System.ComponentModel.Composition.ReflectionModel.ReflectionModelServices來支持默認目錄的緩存。假設你使用標準的屬性編程模型,並且你知道你所有的[Export]都在類型級別上(即它們不在成員上),那麼你可以調用你的目錄中每個部分的GetPartType(part)來獲得類型。

正如Daniel指出的那樣,如果您使用的是其他編程模型,那麼這對您不起作用,但是如果您僅使用MEF附帶的默認目錄,那麼它應該完成這項工作。

1

通常,您並不需要根據類型選擇導出。相反,您可以根據元數據找到「正確」的導出。

查看Exports and metadata上的MEF編程指南部分。

4

這不是你要找的嗎?

public static IEnumerable<Type> GetExportedTypes<T>() 
    { 
     return catalog.Parts 
      .Where(part => IsPartOfType(part, typeof(T).FullName)) 
      .Select(part => ReflectionModelServices.GetPartType(part).Value); 
    } 

    private static bool IsPartOfType(ComposablePartDefinition part, string exportTypeIdentity) 
    { 
     return (part.ExportDefinitions.Any(
      def => def.Metadata.ContainsKey("ExportTypeIdentity") && 
        def.Metadata["ExportTypeIdentity"].Equals(exportTypeIdentity))); 
    } 
+1

剛剛添加缺少的方法IsPartOfType,使這項工作(至少對我來說) – 2014-10-12 18:25:17

1

您可以將導出屬性視爲自定義屬性。裝配體非常大時,我沒有測試性能。

Type[] GetType(Assembly assembly) 
{ 
    return assembly.GetTypes().Where(type => Attribute.GetCustomAttribute(type, typeof(ExportAttribute)).Length > 0).ToArray(); 
} 
相關問題