问题
I'm starting to use MEF, and I have a class with multiple constructors, like this:
[Export(typeof(ifoo))]
class foo : ifoo {
void foo() { ... }
[ImportingConstructor]
void foo(object par1) { ... }
}
I am using catalog.ComposeExportedValue()
when composing to supply the par1
value to second constructor:
...
catalog.ComposeExportedValue(par1Value);
catalog.ComposeParts(this);
...
To hold the components I'm using:
[ImportMany(typeof(ifoo))]
public List<Lazy<ifoo, ifoometadata>> FooList { get; set; }
And to create the foo
instance I'm using the value property, FooList[0].Value
.
Everthing works fine, except that the second constructor of the foo
class is never called. What's wrong?
How do I select the constructor I want to use when MEF instantiates the class?
回答1:
MEF should use the constructor you put the ImportingConstructorAttribute
on. I'm not sure what is happening for you, I wasn't able to reproduce the issue. Here is a test which shows using an ImportingConstructor on a class that also has a default constructor:
[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; }
}
回答2:
Are you passing an instance of the foo class into the ComposeExportedValue method? In that case the object has already been constructed and the constructor can't be called again, so MEF will ignore the constructor imports.
来源:https://stackoverflow.com/questions/2941158/mef-constructor-parameters-with-multiple-constructors