2013-02-19 35 views
2

我使用的是最新的MEF 2預覽版本Codeplex homepage,它應該添加開放式泛型支持。確實如此,但在這種特殊情況下,MEF未能構成通用實現通用接口的:MEF 2無法導入泛型接口的通用實現

public interface IOuter 
{ 
    IInner Value { get; } 
} 

[Export(typeof(IOuter))] 
public class MyOuter : IOuter 
{ 
    [ImportingConstructor] 
    public MyOuter(InnerGenericClass<string, int> value) 
    { 
     this.Value = value; 
    } 

    public IInner Value { get; private set; } 
} 

public interface IInner 
{ 
    void Say(); 
} 
public interface IGenericInner<T, K> : IInner 
{ 
    // something else here 
} 

[Export(typeof(IGenericInner<,>))] 
public class InnerGenericClass<T, K> : IGenericInner<T, K> 
{ 
    public void Say() 
    { 
     Console.WriteLine("{0}, {1}", typeof(T), typeof(K)); 
    } 
} 

class Startup 
{ 
    public void CatalogSetup() 
    { 
     var catalog = new AggregateCatalog(
      new AssemblyCatalog(Assembly.GetExecutingAssembly()) 
      ); 
     var container = new CompositionContainer(catalog, CompositionOptions.DisableSilentRejection); 

     var batch = new CompositionBatch(); 

     container.Compose(batch); 

     var outer = container.GetExportedValue<IOuter>(); 
     outer.Value.Say(); 
    } 
} 

這裏的CompositionExpection

The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information. 

1) No exports were found that match the constraint: 
    ContractName ConsoleApplication1.InnerGenericClass(System.String,System.Int32) 
    RequiredTypeIdentity ConsoleApplication1.InnerGenericClass(System.String,System.Int32) 

Resulting in: Cannot set import 'ConsoleApplication1.MyOuter.Value (ContractName="ConsoleApplication1.InnerGenericClass(System.String,System.Int32)")' on part 'ConsoleApplication1.MyOuter'. 
Element: ConsoleApplication1.MyOuter.Value (ContractName="ConsoleApplication1.InnerGenericClass(System.String,System.Int32)") --> ConsoleApplication1.MyOuter --> AssemblyCatalog (Assembly="ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null") 

Resulting in: Cannot get export 'ConsoleApplication1.MyOuter (ContractName="ConsoleApplication1.IOuter")' from part 'ConsoleApplication1.MyOuter'. 
Element: ConsoleApplication1.MyOuter (ContractName="ConsoleApplication1.IOuter") --> ConsoleApplication1.MyOuter --> AssemblyCatalog (Assembly="ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null") 
甚至當我移動進口的 InnerGenericClass

相同的異常被拋出屬性MyOuter.Value

[Export(typeof(IOuter))] 
public class MyOuter : IOuter 
{ 
    [Import(typeof(InnerGenericClass<string, int>))] 
    public IInner Value { get; private set; } 
} 

是什麼奇怪的,就是,它確實工作,當我改變進口類型IGenericInner

[Export(typeof(IOuter))] 
public class MyOuter : IOuter 
{ 
    [ImportingConstructor] 
    public MyOuter(IGenericInner<string, int> value) 
    { 
     this.Value = value; 
    } 

    public IInner Value { get; private set; } 
} 

什麼是更加古怪,是,它不起作用,導入時通過屬性。

摘要:我不能使用通用接口導入對象財產,因爲可能有IGenericInner接口的多種實現(也是我想導入具體的實現,但是這並不重要)。

我希望在這種情況下我不必繞過MEF。

回答

5

導致您的導出接口IGenericInner <>但要導入特定的類InnerGenericClass MEF未找到正確的部分。您可以導出和導入特定的類或創建InnerGenericClass <兩個出口>是這樣的:

[Export(typeof(IGenericInner<,>))] 
[Export(typeof(InnerGenericClass<,>))] 
public class InnerGenericClass<T, K> : IGenericInner<T, K> { 
    public void Say() { 
     Console.WriteLine("{0}, {1}", typeof(T), typeof(K)); 
    } 
} 

我只是在VS .NET 4.5的項目測試,這和它的作品。 Btw。 MEF 2已經在.NET 4.5中發佈 - 如果可能,我建議使用框架的System.ComponentModel.Composition.dll部分,而不是預覽版本。

UPDATE: 的第三種解決方案(其將與預覽版本5工作)可以另外使用一個字符串合同名。我個人試圖避免這個醜陋的語法的原因,但是沒問題。代碼將如下所示:

[Export(typeof(IOuter))] 
public class MyOuter : IOuter { 
    [ImportingConstructor] 
    public MyOuter([Import("MySpecialInnerGenericClass", typeof(IGenericInner<,>))]InnerGenericClass<string, int> value) { 
     this.Value = value; 
    } 

    public IInner Value { get; private set; } 
} 
[Export("MySpecialInnerGenericClass", typeof(IGenericInner<,>))] 
public class InnerGenericClass<T, K> : IGenericInner<T, K> { 
    public void Say() { 
     Console.WriteLine("{0}, {1}", typeof(T), typeof(K)); 
    } 
} 
+0

不幸的是,我只用了4.0(請參閱問題標籤)。預覽版本中您的建議不起作用。我無法升級到4.5,因爲我仍然有運行WinXP的客戶端。 – mnn 2013-02-20 17:48:19

+0

恩,太糟糕了。我'增加了第三個選項。我嘗試避免這種語法,但它解決了這個問題。 – Andreas 2013-02-21 08:46:32

+0

謝謝,但這確實看起來很醜。我想我不會在我的API的這個特定部分使用MEF。 – mnn 2013-02-22 22:57:41