2010-05-31 111 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