【问题标题】:Trying to understand using a service to open a dialog试图了解使用服务打开对话框
【发布时间】:2015-02-24 21:51:15
【问题描述】:

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

这是我看过的一篇帖子:https://stackoverflow.com/a/1044304/4593652 我有点明白他们的建议,但对于学习的人来说,这还不够。我不是要求任何人为我写这篇文章,只是希望对我应该阅读哪些内容以了解这些部分如何组合在一起提供一些建议。

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

public class OpenDialogService
    {
    public string GetOpenDialog(string title)
    {
        CommonOpenFileDialog dlg = new CommonOpenFileDialog();
        dlg.Title = title;
        dlg.IsFolderPicker = true;
        dlg.AddToMostRecentlyUsedList = true;
        dlg.AllowNonFileSystemItems = false;
        dlg.EnsureFileExists = false;
        dlg.EnsurePathExists = true;
        dlg.EnsureReadOnly = false;
        dlg.EnsureValidNames = true;
        dlg.Multiselect = false;
        dlg.ShowPlacesList = true;

        if (dlg.ShowDialog() == CommonFileDialogResult.Ok)
        {
            return dlg.FileName;
        }
        return null;
    }
}

然后当我的命令被调用时,我在我的 ViewModel 中使用它。

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

【问题讨论】:

  • 答案会有点固执。如果它对你有用,坚持下去,直到你找到更好的方法。这是学习过程的一部分。编程中没有单一的“正确方法”。
  • @walther 我不确定。虽然没有一种方法可以正确编程,但有些模式如果你没有正确实现就不再是那种模式,它们是别的东西。在这种情况下,他没有正确实现服务模式。

标签: c# wpf mvvm


【解决方案1】:

Walther 基本上是对的。

另一篇文章说他可以通过 IOC Container 更改他的服务实现。 IOC 表示“控制反转”-模式,您可以阅读this 文章以获得基本概述。我认为“服务”也来自该模式。另一个流行词是您可以寻找的依赖注入。

【讨论】:

  • 感谢 ec8or。我已经阅读了国际奥委会并观看了一些关于它的教学。还有一段路要走,但我现在对它的处理要好得多,并且比以前更好地理解这些部分是如何组合在一起的。
【解决方案2】:

好的,这里有几个问题。

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

您的代码中缺少的部分是服务的接口,并使用 IoC 将该代码注入您的 ViewModel。

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 代码即可使其在测试期间正常工作。

【讨论】:

  • 谢谢,这有助于我更好地理解在测试我的代码时这些部分是如何组合在一起的。感谢您的指导。
  • 我在我的主视图中设置了我的数据上下文,如下所示,既然我的视图模型构造函数接受了参数,我是否仍然在我的 xaml 中处理它,还是在代码中处理这个更好?
猜你喜欢
  • 2017-05-06
  • 2011-04-29
  • 2012-11-13
  • 1970-01-01
  • 2021-10-28
  • 1970-01-01
  • 2016-07-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多