2013-07-29 45 views
0

我的元數據接口和屬性有基本接口。MEF GetExports <T>()無法正確導入

public interface IBase 
{ 
    string Name { get; } 
} 


public interface IAAAMetaData : IBase 
{ 
    string[] Names { get; } 
} 

[MetadataAttribute] 
[AttributeUsage(AttributeTargets.Method)] 
public class AAAMetaData : ExportAttribute, IAAAMetaData 
{ 
    public AAAMetaData(string contract) 
    { 
     Name = contract; 
    } 

    public AAAMetaData(string[] contracts) 
    { 
     Names = contracts; 
    } 
    public string Name { get; set; } 
    public string[] Names { get; set; } 
} 


public interface IBBBMetaData : IBase 
{ 
    string[] Names { get; } 
} 

[MetadataAttribute] 
[AttributeUsage(AttributeTargets.Method)] 
public class BBBMetaData : ExportAttribute, IBBBMetaData 
{ 

    public BBBMetaData(string contract) 
    { 
     Name = contract; 
    } 

    public BBBMetaData(string[] contracts) 
    { 
     Names = contracts; 
    } 
    public string Name { get; set; } 
    public string[] Names { get; set; } 
} 

這裏是我的插件:

[AAAMetaData("Test1")] 
    public void Plugin1(object sender, EventArgs e) 
    { 
     sender = "Plugin1"; 
    } 

    [BBBMetaData("Test2")] 
    public void Plugin2(object sender, EventArgs e) 
    { 
     sender = "Plugin2"; 
    } 

現在,當我嘗試獲得出口我得到錯誤的結果。下面是我使用來獲得出口代碼:

var exports = _container.GetExports<Action<object, EventArgs>, IAAAMetaData>(); 

GetExprts<T>()我得到該列表中兩個項目的結果。如果我打開列表並查看其中導入Plugin2的項目。這裏有什麼問題? IAAAMetaDataIBMetaData是完全不同的東西。你甚至不能投IAAAMetaDataIBBBMetaData。任何人都可以解釋這裏發生了什麼?

感謝您的幫助!

+0

看看這個[SO條目](http://stackoverflow.com/questions/1037795/getting-an-export-from-an-mef-container-given-only-a-type-in​​stance)。 – pasty

+0

@pasty我在您提供的鏈接中看不到有用的信息。也許我不能很好地解釋我的問題。如果你對理解我的問題有任何疑問,請告訴我。 – Dilshod

回答

1

背後的原因是兩個元數據接口具有完全相同的屬性。每個屬性的相同類型和名稱。例如,如果您將接口更改爲:

public interface IAAAMetaData : IBase 
{ 
    string[] AAA_Names { get; } 
} 

public interface IBBBMetaData : IBase 
{ 
    string[] BBB_Names { get; } 
} 

您將獲得您期望的單一導出。

這在元數據過濾種解釋和DefaultValueAttribute的Exports and Metadata (CodePlex MEF site)部分:

當specifiy元數據視圖,隱式過濾將想到 匹配只有那些含有所述元數據屬性的出口在視圖中定義了 。

當然,如果導出方法的簽名不同,就不會發生這種情況。嘗試添加一個額外的變量,你會得到單一的導出。另一種方法是使用合同名稱ExportAttributeImportAttribute

+0

你是對的,我早點發現了問題,但忘了在這裏更新。謝謝! – Dilshod

1

我沒有意識到有一個具有多個泛型參數的方法,但由於您沒有收到編譯器錯誤,我假設確實有一個。但是,第二個參數可能不是合同類型。 MEF中的合同由名稱指定。因此,試試這個:

var exports = _container.GetExports<Action<object, EventArgs>>("Test1"); 
+0

在我的情況下,我不能把合同名稱。由於其他原因,我正在使用「Test1」。 – Dilshod

0

IMO IAAAMetaDataIBBBMetaData是沒有什麼不同。它們實際上是相同的。

證明 - GetExports檢索同一INNNMetaData類型的兩個項目,這取決於輸入是IAAAMetaDataIBBBMetaData。因爲相同的基本接口,你實際上可以寫:

var exports = container.GetExports<Action<object, EventArgs>, IBase>(); 

,你會得到類型基準值=>的Test1和Test2的兩個項目。

因此,使用你的代碼,我發現用的是合同名稱的唯一解決方案:

var exports = container.GetExports<Action<object, EventArgs>, IAAAMetaData>().FirstOrDefault(iaaaa => iaaaa.Metadata.Name == "Test1"); 

在這種情況下,GetExports接口參數是無關緊要的。

+0

var exports = container.GetExports ,IAAAMetaData>()。FirstOrDefault(iaaaa => iaaaa.Metadata.Name ==「Test1」);它返回[WHAT]。如果我爲這兩個插件「Test1」做了什麼?我只是不想要列表中的第一項。將會有很多使用這些屬性的插件。 – Dilshod

+0

在調試你的代碼時,查看** exports **並查看每個項目的類型 - 兩個項目都具有相同的類型!爲了從某些特定類型中提取插件,您可能需要FilteredCatalog和命名屬性。 – pasty