C# 试图理解如何使用服务打开对话框

C# 试图理解如何使用服务打开对话框,c#,wpf,mvvm,C#,Wpf,Mvvm,我已经阅读了有关使用mvvm模式打开对话框的讨论。我见过几个例子,说使用一个服务,但我不明白所有的部分是如何组合在一起的。我发布这个问题是为了寻求指导,以便更好地理解我遗漏了什么。我将在下面发布我所拥有的,它确实有效,但从我在这些帖子中看到的情况来看,我做得不对,或者可能做得不够有效。我看到了对话框接口的创建位置,然后是使用该接口执行实际工作的类。然后在ViewModel中,一个构造函数在这个接口中传递,这是真正让我困惑的部分,不确定传递它的是什么,没有足够的信息来连接点,也不确定我缺少了什么

我已经阅读了有关使用mvvm模式打开对话框的讨论。我见过几个例子,说使用一个服务,但我不明白所有的部分是如何组合在一起的。我发布这个问题是为了寻求指导,以便更好地理解我遗漏了什么。我将在下面发布我所拥有的,它确实有效,但从我在这些帖子中看到的情况来看,我做得不对,或者可能做得不够有效。我看到了对话框接口的创建位置,然后是使用该接口执行实际工作的类。然后在ViewModel中,一个构造函数在这个接口中传递,这是真正让我困惑的部分,不确定传递它的是什么,没有足够的信息来连接点,也不确定我缺少了什么

这是我看过的一篇帖子:我有点明白他们的建议,但这对学习的人来说还不够。我不是要求任何人为我写这篇文章,只是希望能得到一些建议,让我了解这些作品是如何组合在一起的

在我的代码中,我有这样一个类:(这很有效,我只是觉得我在其他帖子上读到的东西中遗漏了一些东西)

然后在调用命令时,我在ViewModel中使用它

path = new OpenDialogService().GetOpenDialog("...");

沃尔特基本上是对的


另一篇帖子说他可以通过IOC容器更改他的服务实现。IOC意味着“控制反转”模式,你们可以阅读这篇文章来获得一个基本的概述。我认为“服务”也来自于这种模式。另一个流行词是依赖注入,您可以寻找它。

好的,这里有几个问题

正如@ec8or指出的,您应该仔细阅读“控制反转”(InversionofControl,IoC),因为几乎所有MVVM框架都使用它。服务模式还依赖于IoC,因此测试更容易

代码中缺少的位是服务的接口,并使用IoC将代码注入到ViewModels中

public interface IOpenDialogService
{
    string GetOpenDialog(string title);
}

public class OpenDialogService : IOpenDialogService ...
然后在ViewModel中使用它

public class MyViewModel
{
    private IOpenDialogService openDialogService;

    // service injected by the IoC
    public MyViewModel(IOpenDialogService openDialogService)
    {
        this.openDialogService = openDialogService;
    }

    public void DoCommand()
    {
        var path = openDialogService.GetOpenDialog("...");
    }
}
那么为什么要这样做呢

测试ViewModel时,您不希望打开的对话框突然弹出,从而导致测试失败或挂起。因此,在测试期间,我们可以将
IOpenDialogService
的实现更改为返回常量的实现。然后,当您测试ViewModel而不是打开对话框时,代码将只获取常量并继续运行,从而允许测试完成


通过这种方式,您不需要修改ViewModel代码,只需在测试过程中使其正常工作。

答案都有点自以为是。。如果它对你有效,坚持下去直到你找到更好的方法。这是学习过程的一部分。编程中没有一种“正确的方法”。@沃尔特,我对此不确定。虽然没有一种方法可以正确编程,但有些模式如果没有正确实现,就不再是那种模式,而是另外一种模式。在这种情况下,他没有正确实现服务模式。谢谢ec8or。我读过关于国际奥委会的书,并观看了一些关于它的教学。还有很长的路要走,但我现在对它有了更好的处理,并且比以前更好地理解了各个部分是如何组合在一起的。谢谢,这帮助我更好地理解了关于测试代码的各个部分是如何组合在一起的。我很感谢您的指导。我在主视图中设置了datacontext,如下所示,既然viewmodel构造函数接受了参数,我还会在xaml中处理这个问题吗?还是在代码中处理这个问题更好?
public class MyViewModel
{
    private IOpenDialogService openDialogService;

    // service injected by the IoC
    public MyViewModel(IOpenDialogService openDialogService)
    {
        this.openDialogService = openDialogService;
    }

    public void DoCommand()
    {
        var path = openDialogService.GetOpenDialog("...");
    }
}