用MEF实例化两次ViewModel

本文关键字:两次 ViewModel MEF 实例化 | 更新日期: 2023-09-27 18:15:06

我试图用MEF创建一个简单的模块化MVVM应用程序。我有一个ViewModel类和一个UserControl作为视图。我通过DataTemplate将两者连接起来,如下所示:

<DataTemplate DataType="{x:Type local:MyViewModel}">
    <local:MyView />
</DataTemplate>

在View中,我将ViewModel定义为StaticResource,以使绑定变得简单:

<UserControl.Resources>
    <local:MyViewModel x:Key="ViewModel" />
</UserControl.Resources>

然后我这样绑定:

<Grid DataContext="{StaticResource ResourceKey=ViewModel}">
    <TextBlock Text="{Binding Text}" />
</Grid>

没有MEF,这一切都能正常工作。然而,由于我的目标是模块化,我使用MEF来发现我的ViewModel类。我有一个Export属性在我的ViewModel类:

[Export(typeof(MyViewModel))]
public class MyViewModel
{
    // ...
}

和我使用MEF动态加载ViewModel到我的shell在App.xaml.cs:

private void Application_Startup(object sender, StartupEventArgs e)
{
    var shell = new MainWindow();
    var catalog = new AssemblyCatalog(this.GetType().Assembly);
    var container = new CompositionContainer(catalog);
    shell.Contents.ViewModel = container.GetExportedValues<MyViewModel>().First();
    shell.Show();
}

现在,在这一点上,MEF在加载vm时创建了我的ViewModel的一个实例,而我的View在将vm声明为资源时创建了另一个实例。(这很容易通过在构造函数中设置断点来检查。)

问题是,我应该如何将MEF创建的实例传递给我的资源声明?我可以将特定的实例声明为资源吗?

DropBox链接与完整的代码:https://www.dropbox.com/sh/pbdl029d26sx7gl/AAA6po50dLjbJSoNPBhCyWZ3a?dl=0

用MEF实例化两次ViewModel

MyViewModel的创建完全基于程序执行的顺序,但是您可以设置CreationPolicy使您的实例成为单例,以便您的代码和资源都引用同一个实例。

[出口(typeof (MyViewModel)), PartCreationPolicy (CreationPolicy.Shared)]

边注:为了使用MEF,微软出于某种原因隐藏了。net框架中CompositionInitializer和CompositionHost的实现。试着用谷歌搜索并从微软导入这两个类,而不是直接使用compostioncontainer。

好的,我要做的是。

我有两个实例,因为有一次MEF在导入ViewModels时实例化了它们,然后另一次WPF在创建ViewModel资源时创建了它们。我认为解决方案不是直接创建资源,但我不知道如何做到这一点。然后是资源注入,然后是DataContextSpy,从这里的问题:https://stackoverflow.com/a/5402653/5219911

下面是该主题的直接链接:http://www.codeproject.com/Articles/27432/Artificial-Inheritance-Contexts-in-WPF

我现在使用的资源是一个DataContextSpy,通过它我可以接触到创建DataTemplate时使用的ViewModel实例。

在我的视图的资源中,我定义然后我把根元素的DataContext设置为这个资源:DataContext="{绑定源={StaticResource = ResourceKey=ViewModel},路径= DataContext} "

现在,不幸的是,我不能单独获得智能感知支持,因为DataContextSpy是真正的DataContext的代理,所以我必须手动设置设计时DataContext类型:d: DataContext = " {d: DesignInstance Type = viewModel: MyViewModel}"