【问题标题】:MEF Constructor Parameters with Multiple Constructors具有多个构造函数的 MEF 构造函数参数
【发布时间】:2010-05-31 02:55:10
【问题描述】:

我开始使用 MEF,并且我有一个具有多个构造函数的类,如下所示:

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

我在撰写时使用catalog.ComposeExportedValue() 来提供par1 第二个构造函数的值:

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

保存我正在使用的组件:

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

为了创建 foo 实例,我使用了 value 属性 FooList[0].Value

一切正常,除了 foo 类的第二个构造函数从未被调用。怎么了?

MEF实例化类时如何选择要使用的构造函数?

【问题讨论】:

  • 看看stackoverflow.com/questions/2008133/mef-constructor-injection ...这不是完全同一个问题,但接受的答案为导入构造函数提供了一些线索,这可能会有所帮助。
  • 是的,事实上我正在使用 Daniel Plaisted 的答案,问题是我找不到使用多个构造函数定义创建 mef 实例的任何示例。

标签: c# .net mef multiple-constructors


【解决方案1】:

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; }
}

【讨论】:

  • 谢谢丹尼尔,它是这样工作的,但现在我遇到了另一个问题:MEF 构造函数导入在使用派生类时不起作用,就像我们有一个 Foo2 类,它在您的示例中继承自 Foo 并更改其余的从 Foo 导出/导入所有派生类,不调用具有基类 (Foo) 参数的构造函数。也许是设计使然,不要一直检查所有基类的构造函数。但是我在基类(Foo)中使用了一个字段导入并且它可以工作,所以我使用这个workround而不是构造函数导入,至少现在是这样。感谢您的帮助丹尼尔。
  • @InterWAS 这是设计使然。这就是 .NET 中的构造函数的工作方式——在创建对象时只调用一个构造函数,它不能是基类构造函数。派生类可以在其构造函数中调用基类的构造函数。在您的情况下,属性/字段导入可能更有意义。
【解决方案2】:

您是否将 foo 类的实例传递给 ComposeExportedValue 方法?在这种情况下,对象已经被构造并且构造函数不能被再次调用,因此 MEF 将忽略构造函数的导入。

【讨论】:

  • 不,在 ComposeExportedValue() 中,我传递了我想在构造函数中注入的值:catalog.ComposeExportedValue(par1Value);我的问题是任何提供的构造函数参数都被忽略了,类 foo 仅使用第一个构造函数进行实例化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-04
  • 2011-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-08
  • 1970-01-01
相关资源
最近更新 更多