在符合MVVM最佳实践的同时,代码应该在哪里打开EXE?

时间:2016-04-02 09:44:47

标签: c# wpf mvvm

我正在尝试实现MVVM设计模式。我有一个方法,在我的代码后面的文件绑定到一个按钮点击事件,打开一个教学视频,如下所示:

    private void OpenvideoButton_MouseDown(object sender, MouseButtonEventArgs e)
    {
        try
        {
            Process.Start(@"Instructional_Video.wmv");
        }catch
        {
            MessageBox.Show("Error playing instructional video");
        }

        e.Handled = true;
    }

我的问题是我应该在MVVM架构中将代码放在哪里? 由于视频是一个图形对象,因为MessageBox我正在考虑将其保留在代码中,但我也非常谨慎地将代码留在那里。

在符合MVVM最佳实践的情况下,我应该在哪里保留上述代码?

1 个答案:

答案 0 :(得分:1)

代码,"会谈"外部世界(操作系统,文件系统,数据库,Web服务,UI层等)应放在服务中 - 当您为视图模型编写单元测试时,可以模拟的对象。

使用依赖注入容器(如MEF,AutoFac,NInject等)将服务注入视图模型是一种很好的做法。

这样的事情:

public interface IPlayerLauncher
{
    void Launch(string fileName);
}

public interface IDialogService
{
    void ShowMessageBox(string message);
}

public class SomeViewModel
{
    private readonly IPlayerLaucher playerLauncher;
    private readonly IDialogService dialogService;

    private void HandleOpenVideo()
    { 
        try
        {
            playerLauncher.Launch("Instructional_Video.wmv");
        }
        catch
        {
            dialogService.ShowMessageBox("Error playing instructional video");            
        }
    }

    public SomeViewModel(IPlayerLaucher playerLaucher, IDialogService dialogService)
    {
        this.playerLauncher = playerLauncher;
        this.dialogService = dialogService;
        OpenVideoCommand = new RelayCommand(HandleOpenVideo);
    }

    public ICommand OpenVideoCommand { get; }
}

public class PlayerLaucher : IPlayerLauncher
{
    public void Lauch(string fileName)
    {
        Process.Start(fileName);
    }
}

public class DialogService : IDialogService
{
    public void ShowMessageBox(string message)
    {
        MessageBox.Show(message);
    }
} 

RelayCommand(也是DelegateCommand)是ICommand的实现,它执行传递的委托。互联网上有很多实施样本。

不是处理点击事件,而是将按钮绑定到OpenVideoCommand。 请注意,像这样的异常处理不是一个好的选择,但这与此问题无关。