c# - ViewModel 使用 MEF 实例化了两次

标签 c# wpf xaml mvvm mef

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

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

在 View 中,我将 ViewModel 定义为 StaticResource,以简化绑定(bind):
<UserControl.Resources>
    <local:MyViewModel x:Key="ViewModel" />
</UserControl.Resources>

然后我像这样绑定(bind):
<Grid DataContext="{StaticResource ResourceKey=ViewModel}">
    <TextBlock Text="{Binding Text}" />
</Grid>

在没有 MEF 的情况下,这一切都按预期工作。但是,由于我的目标是模块化,所以我使用 MEF 来发现我的 ViewModel 类。我的 ViewModel 类上有一个 Export 属性:
[Export(typeof(MyViewModel))]
public class MyViewModel
{
    // ...
}

我使用 MEF 将 ViewModel 动态加载到 App.xaml.cs 中的 shell 中:
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

最佳答案

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

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

旁注:为了使用 MEF,Microsoft 出于某种原因从 .Net Framework 中隐藏了 CompositionInitializer 和 CompositionHost 的实现。尝试 google 并从 Microsoft 导入 2 个类,而不是直接使用 CompositionContainer。您将在使用 MEF 时获得更好的体验。

关于c# - ViewModel 使用 MEF 实例化了两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32826634/

相关文章:

c# - 如何访问 Windows 中的特殊目录?

.net - 如何在 WPF 中保持窗口靠后?

c# - 如何从 MahApps.Metro 模板中删除窗口命令?

c# - 创建一个方形边框,内部有图像,宽度和高度取决于统一的网格列

c# - WPF WindowChrome : Edges of maximized Window are out of the screen

c# - .Net 无法连接到 Apple 推送通知服务

c# - 使用传递给方法的 lambda 表达式会减慢 Entity Framework 查询的速度吗?

c# - 我什么时候必须编译asp.net 4.0 项目?

c# - 将文件扩展名与 WPF 应用程序相关联

c# - 在 WPF 中,如何绑定(bind)到 ViewModel 并将各种 XAML 元素绑定(bind)到 ViewModel 的方法?