使用 Prism 时,将 vm 注入视图与在 XAML 中定义它相比有什么优势?

What is the advantage of injection vm into view vs defining it in XAML when using Prism?

我通常直接在 XAML 中定义我的视图模型如下:

<Window.DataContext>
    <vm:MyViewModel />
</Window.DataContext>

否则,当 ViewModel 具有构造函数参数时,使用 ObjectDataProvider。

在 Prism 5 的官方 pdf 文档中,他们在代码隐藏中定义它并使用 MEF/Unity 注入视图模型,如下所示:

[Export] 
public partial class Shell : Window 
{ 
    public Shell() { InitializeComponent(); } 

    [Import] 
    ShellViewModel ViewModel
    {
        set { this.DataContext = value; } 
    }
}

我个人将 DI 与 MEF 一起使用,但在那种特殊情况下,我真的看不到注入 VM 的任何优势,并认为这是对 DI 的过度使用。
(假设:我没有为模拟整个 ViewModel 的 GUI 编写任何大型单元测试,因为我的单元测试依赖于服务层。即使在那种情况下,我也可以在测试用例中动态切换 DataContext .).
但可能是我遗漏了什么。

那么,两种方法之间的 pros/cons 是什么?

让 View 负责创建 ViewModel 有很多问题,但我仅举一个例子;依赖管理。假设您定义了一个虚拟机:

public class MyViewModel
{
    public MyViewModel() { }
}

假设您在 XAML 中创建了视图:

<Window.DataContext>
     <local:MyViewModel />
</Window.DataContext>

现在,当您的 VM 需要服务或依赖项时,您会怎么做?

public class MyViewModel
{
    public MyViewModel(IMyService myservice) { }
}

更糟糕的是,如果该服务有自己的依赖项怎么办?

好吧,由于显而易见的原因,现在在 XAML 中定义它肯定是不可行的。如果您在代码中定义 DataContext,则会遇到与 XAML 中类似的问题;依赖管理。如果您注入了 ViewModel,那么您将永远不必担心 ViewModel 需要哪些依赖项,并且您永远不必修改代码隐藏以适应添加到 VM ctor 的新依赖项。它会起作用的。当您的 VM 在不同的程序集中并跨多个平台共享时,或者当您需要根据构建配置或设备更改要使用的依赖项的具体实现时,这尤其有用。