我正在尝试使用MEF和MVVM构建WPF应用程序。我正在导出我的ViewModel,但我希望我的ViewModel接受构造函数中的Model参数:我将创建一个特定的Model并将其提供给ViewModel的构造函数。我试图了解ImportingConstructorAttribute是如何工作的,似乎是拥有自定义构造函数的方法。但我无法弄清楚如何使用它。
有人可以举例说明使用ImportingConstructorAttribute吗?
提前致谢
答案 0 :(得分:5)
你走了。类Test
通过构造函数导入IFoo
实例:
public class Program
{
public static void Main(string[] args)
{
var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var container = new CompositionContainer(catalog);
Test test = container.GetExportedValue<Test>();
}
}
[Export]
public class Test
{
private IFoo foo;
[ImportingConstructor]
public Test(IFoo foo)
{
this.foo = foo;
}
}
public interface IFoo
{
}
[Export(typeof(IFoo))]
public class Foo : IFoo
{
}
编辑以回应评论:我认为“由我们初始化而不是共享”你的意思是你想要手动实例化一个非属性的非MEF类并将其注入MEF部分的依赖关系。通常你会这样做:
public class Program
{
public static void Main(string[] args)
{
var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var container = new CompositionContainer(catalog);
// create and add non-MEF instance explicitly to container
var nonMEF = new NonMefClass();
container.ComposeExportedValue<IFoo>("Test.foo", nonMEF);
Test test = container.GetExportedValue<Test>();
}
}
[Export]
public class Test
{
private IFoo foo;
[ImportingConstructor]
public Test([Import("Test.foo", typeof(IFoo))] IFoo foo)
{
this.foo = foo;
}
}
public interface IFoo
{
}
public class NonMefClass : IFoo
{
}
使用ComposeExportedValue
向容器明确添加实例的替代方法是使用属性导出。然后,您可以根据需要在属性getter中初始化非MEF对象:
public class Bar
{
[Export("Test.foo", typeof(IFoo))]
public IFoo Foo
{
get
{
return new NonMefClass();
}
}
}
编辑以回应评论2 :首先警告;在MEF预览8中,ImportingConstructor和PartCreator似乎不能很好地协同工作,可能是因为PartCreator只是一个尚未经过充分测试的样本。使用属性注入导入PartCreator实例。
现在回答你的问题;如果您只是想强制MEF创建依赖项的多个实例,那么您只需要将导入属性[Import("Test.foo", typeof(IFoo), RequiredCreationPolicy=CreationPolicy.NonShared)]
。
如果你为每个实例完成不同的组合,那么事情就会复杂一些。您不能真正拥有单个部分(即具有MEF属性的类),并且除非您设置了多个容器,否则它将针对不同的零件实例进行不同的组合。相反,我在这种情况下所做的是创建从公共类继承的多个部分。然后,每个所需的组合有1个子类:
public class Test
{
private IFoo foo;
public Test(IFoo foo)
{
this.foo = foo;
}
}
[Export]
public class TestComposition1 : Test
{
[ImportingConstructor]
public Test([Import("TestComposition1.foo", typeof(IFoo))] IFoo foo)
: base(foo)
{
}
}
[Export]
public class TestComposition2 : Test
{
[ImportingConstructor]
public Test([Import("TestComposition2.foo", typeof(IFoo))] IFoo foo)
: base(foo)
{
}
}
这当然要求您考虑到有限数量的替代作品。如果在设计时无法枚举所需组合的数量,则需要更复杂的东西,可能涉及PartCreator和基于零件元数据的动态选择。