2010-05-31 108 views
8

我開始使用MEF,和我有多個構造一類,像這樣:與多個構造MEF構造函數的參數

[Export(typeof(ifoo))] 
class foo : ifoo { 
    void foo() { ... } 
    [ImportingConstructor] 
    void foo(object par1) { ... } 
} 

組成供應par1 值第二,當我使用catalog.ComposeExportedValue()構造函數:

... 
catalog.ComposeExportedValue(par1Value); 
catalog.ComposeParts(this); 
... 

要保持組件我使用:

[ImportMany(typeof(ifoo))] 
public List<Lazy<ifoo, ifoometadata>> FooList { get; set; } 

而要創建foo實例,我使用的是value屬性FooList[0].Value

寄託都工作得很好,除了foo類的第二個構造函數永遠不會被調用。怎麼了?

如何選擇我想使用的時候MEF實例化類的構造函數?

+0

看一看http://stackoverflow.com/questions/2008133/mef-constructor-injection ......這是不是*完全相同的問題,但接受的答案對導入構造函數有一些幫助。 – 2010-05-31 03:12:50

+0

是的,實際上我使用Daniel Plaisted的答案,問題是我找不到使用多個構造函數定義創建mef實例的任何示例。 – InterWAS 2010-05-31 14:17:20

回答

8

MEF應該使用構造你把ImportingConstructorAttribute上。我不確定發生了什麼事情,但我無法重現此問題。下面是測試表示採用的一類也有一個默認的構造函數的ImportingConstructor:

[TestClass] 
public class MefTest 
{ 
    public const string ConstructorParameterContract = "FooConstructorParameterContract"; 

    [TestMethod] 
    public void TestConstructorInjectionWithMultipleConstructors() 
    { 
     string ExpectedConstructorParameterValue = "42"; 

     var catalog = new TypeCatalog(typeof(Foo), typeof(FooImporter)); 
     var container = new CompositionContainer(catalog); 

     container.ComposeExportedValue<string>(ConstructorParameterContract, ExpectedConstructorParameterValue); 

     var fooImporter = container.GetExportedValue<FooImporter>(); 

     Assert.AreEqual(1, fooImporter.FooList.Count, "Expect a single IFoo import in the list"); 
     Assert.AreEqual(ExpectedConstructorParameterValue, fooImporter.FooList[0].Value.ConstructorParameter, "Expected foo's ConstructorParameter to have the correct value."); 
    } 
} 

public interface IFoo 
{ 
    string ConstructorParameter { get; } 
} 

[Export(typeof(IFoo))] 
public class Foo : IFoo 
{ 
    public Foo() 
    { 
     ConstructorParameter = null; 
    } 

    [ImportingConstructor] 
    public Foo([Import(MefTest.ConstructorParameterContract)]string constructorParameter) 
    { 
     this.ConstructorParameter = constructorParameter; 
    } 


    public string ConstructorParameter { get; private set; } 
} 

[Export] 
public class FooImporter 
{ 
    [ImportMany] 
    public List<Lazy<IFoo>> FooList { get; set; } 
} 
+0

感謝丹尼爾, 它的工作方式,但現在我堅持另一個問題: MEF構造函數導入不使用派生類,如果我們有一個Foo2類繼承自Foo在你的例子,並改變其餘的出口/從Foo導入所有派生類,帶有基類(Foo)參數的構造函數未被調用。也許它的設計,不要檢查所有基類的構造函數。 但我使用基類(Foo)中的字段導入,它的工作原理,所以我至少現在使用這個workround而不是構造函數導入。 謝謝你的幫助丹尼爾。 – InterWAS 2010-05-31 20:45:39

+0

@InterWAS這是設計。這就是.NET中的構造函數的工作原理 - 當您創建對象時,您只能調用一個構造函數,並且它不能成爲基類構造函數。派生類可以在其構造函數中調用基類的構造函數。在您的情況下,屬性/字段導入可能更有意義。 – 2010-06-01 01:45:23

3

您是否將foo類的實例傳遞給ComposeExportedValue方法?在這種情況下,該對象已經被構造並且構造函數不能被再次調用,所以MEF將忽略構造函數的導入。

+0

否,在ComposeExportedValue()我通過我想在構造注入的值: catalog.ComposeExportedValue(par1Value); 我的問題是,任何sup構造函數參數都被忽略,並且類foo只使用第一個構造函數即時化。 – InterWAS 2010-05-31 14:09:53