2014-01-07 40 views
4

我知道,從MEF 2開始,MEF支持將開放泛型類型組合爲封閉類型。我試圖從添加到相同組合容器的兩個不同程序集導出的類型中編寫一個封閉類型,並且收到一個ImportCardinalityMismatchException。我爲其中一個程序集使用了約定,因爲它不在我的控制之下。對於其他我使用過的屬性。在MEF 2中使用封閉類型編寫開放式類型

我不完全確定如何說出我的問題,因爲我發現泛型術語相當混亂,但我期待編寫新的封閉類型,而不必明確實現我自己的類,從Foo繼承,並提供它我的FooUser類型參數。我不知道這是否是我如何做這件事的問題,或者是否與類型在不同的程序集中有關。

在一個組裝我有以下幾點:

public class Foo<T> where T : Bar {} 
public class Bar {} 

在另一個組裝我有以下幾點:

[Export] 
public class Bar2 : Bar {} 

[Export] 
public class Something 
{ 
    [ImportingConstructor] 
    public Something([Import(typeof(Foo<>))] Foo<Bar2> foo) {} 
} 

在我的註冊碼我也做了以下內容:

var conventions = new RegistrationBuilder(); 
conventions.ForType(typeof(Foo<>)).Export(); 

var aggregateCatalog = new AggregateCatalog(); 
var catalog = new AssemblyCatalog(typeof(Foo<>).Assembly, conventions); 
aggregateCatalog.Catalogs.Add(catalog); 

catalog = new AssemblyCatalog(typeof(Something).Assembly); 
aggregateCatalog.Catalogs.Add(catalog); 

catalog = new AssemblyCatalog(typeof(Bar2).Assembly); 
aggregateCatalog.Catalogs.Add(catalog); 

var container = new CompositionContainer(aggregateCatalog, CompositionOptions.DisableSilentRejection); 
var batch = new CompositionBatch(); 
batch.AddExportedValue(container); 
container.Compose(batch); 

後來我嘗試導出我的價值如此:

container.GetExportedValue<Something>(); 

異常:拋出該異常: 「沒有出口找到匹配約束: ContractName美孚(BAR2) RequiredTypeIdentity美孚(BAR2)」(System.ComponentModel.Composition.ImportCardinalityMismatchException) 一個System.ComponentModel.Composition。 ImportCardinalityMismatchException被拋出:「沒有出口找到匹配約束: ContractName美孚(BAR2) RequiredTypeIdentity美孚(BAR2)」

我看着我的約定實例,並在容器我有我的部分即富{ 0},Bar2和Something。但是,我仍然收到System.ComponentModel.Composition.ImportCardinalityMismatchException。

我已經看到這在更抽象的情況下完成,說一個人有IRepository但沒有一個更具體的東西或跨越組件的項目。任何援助將不勝感激。除了任何有用的東西,我可能只是從違規類型中繼承並完成它。

編輯:我剛剛構建了一個非常簡單的例子,上面詳細介紹了我實際上在我的現實世界項目中做了一些不同於我在這裏的事情,而且我有不同的結果。我已經重新命名了幾個類型,以使它們符合我簡化的示例。

組合物產生單一組合物錯誤。根源在下面提供。查看CompositionException.Errors屬性以獲取更多詳細信息。

1)出口沒有發現匹配的約束: ContractName CompositionTestLibrary.Foo(CompositionTestLibrary2.Bar2) RequiredTypeIdentity CompositionTestLibrary.Foo(CompositionTestLibrary2.Bar2)

,導致:無法設置進口「CompositionTest.Something。部分'CompositionTest.Something'上的.ctor(Parameter =「foo」,ContractName =「CompositionTestLibrary.Foo(CompositionTestLibrary2.Bar2)」)。 Element:CompositionTest.Something..ctor(Parameter =「foo」,ContractName =「CompositionTestLibrary.Foo(CompositionTestLibrary2.Bar2)」) - > CompositionTest.Something - > AssemblyCatalog(Assembly =「CompositionTest,Version = 1.0.0.0 ,Culture = neutral,PublicKeyToken = null「)

導致:無法從部件'CompositionTest.Something'中導出'CompositionTest.Something(ContractName =」CompositionTest.Something「)''。 (Assembly =「CompositionTest,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null」)

+0

對我來說很好。也許你可以向我們展示如何創建目錄並執行組合?另外,你確定你正在使用具有正確程序集的'conventions'變量,即定義了'Foo '的變量嗎? –

+0

我是。在我的真實代碼中,像我上面的示例一樣,我將相同的RegistrationBuilder傳遞給每個目錄。 –

回答

1

(作者:在下面的行,你不應該使用conventions變量,所以你應該改變

catalog = new AssemblyCatalog(typeof(FooUser).Assembly, conventions); 

catalog = new AssemblyCatalog(typeof(FooUser).Assembly); 

使用conventions這裏將有效地不從組件,其中出口任何東西FooUserSomething已定義,因此您將無法獲得Something的組合值。刪除它將允許導出和編輯Something

+0

不幸的是,情況並非如此。刪除該參數什麼也不做。 –

相關問題