2012-09-10 116 views
5

更新:我應該嘗試通過DI容器來處理它,還是在這裏是一個錯誤的抽象層次?MEF和ABSTRACT FACTORY

我想使用MEF(.NET 4.5)實現ABSTRACT FACTORY。

它不工作對我來說...

的組成保持不變。由於以下錯誤,更改被拒絕:

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

1)出口沒有發現匹配的約束:

ContractName Mef3.Factory

RequiredTypeIdentity Mef3.Factory ,導致:無法設置進口「Mef3.Program._factory(ContractName =「MEF3。工廠「)'部分'Mef3.Program'。

元素:Mef3.Program._factory(ContractName = 「Mef3.Factory」) - > Mef3.Program

是它做它在MEF的正確方法? 如何將id轉發到Foo/Bar ctors?

代碼:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var program = new Program(); 
     program.Run(); 
    } 

    readonly CompositionContainer _container; 

    public Program() 
    { 
     var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly()); 
     _container = new CompositionContainer(catalog); 
     _container.ComposeParts(this); 
    } 

    [Import] 
    public Factory _factory; 

    public void Run() 
    { 
     var foo = _factory.GetInstance("foo", 123); 
     Console.WriteLine(foo is Foo); 
    } 
} 

[Export] 
public class Factory 
{ 
    private readonly ExportFactory<Foo> _fooFactory; 
    private readonly ExportFactory<Bar> _barFactory; 

    [ImportingConstructor] 
    public Factory(ExportFactory<Foo> fooFactory, ExportFactory<Bar> barFactory) 
    { 
     _fooFactory = fooFactory; 
     _barFactory = barFactory; 
    } 

    public Base GetInstance(string name, int id) 
    { 
     switch (name) 
     { 
      case "foo": 
       return _fooFactory.CreateExport().Value; 

      case "bar": 
       return _barFactory.CreateExport().Value; 
     } 

     throw new ArgumentException(); 
    } 
} 

public class Foo : Base 
{ 
    [ImportingConstructor] 
    public Foo([Import("Id")] int id) 
    { 
    } 
} 

public class Bar : Base 
{ 
    [ImportingConstructor] 
    public Bar([Import("Id")] int id) 
    { 
    } 
} 

[InheritedExport] 
public abstract class Base 
{ 
} 

回答

1

問題看起來你的[導入( 「ID」)在Foo和Bar引起的。沒有合同名稱爲「Id」的導出。一般來說,MEF不允許你在運行時傳入進口,你需要能夠在組合時滿足整個圖形,否則它將無法工作。如果您想使用MEF來完成這個特定場景,您應該刪除Foo和Bar上的ImportingConstructor,並在Base類上添加一個SetId方法,並讓您的工廠在調用GetInstance時調用它。

+0

謝謝。我刪除了Foo/Bar ctor參數。它引發同樣的異常。 –

+0

使用屬性注入爲id看起來很奇怪,因爲它不是可選的。你認爲這種情況不適合DI模式嗎?是MEF唯一的問題嗎?我應該使用其他DI容器還是DI只是一個錯誤的抽象級別? –

+0

有人試過這段代碼嗎?我是唯一拋出異常的人嗎? –