凡存储在MVVM应用程序设置/状态 [英] Where to store application settings/state in a MVVM application

查看:174
本文介绍了凡存储在MVVM应用程序设置/状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试用MVVM的第一次真正喜欢的职责分离。当然,任何设计模式只解决了许多问题 - 不是所有的。所以我试图找出在哪里存储应用程序状态和在哪里存储应用程序范围的命令。

I'm experimenting with MVVM for the first time and really like the separation of responsibilities. Of course any design pattern only solves many problems - not all. So I'm trying to figure out where to store application state and where to store application wide commands.

比方说我的应用程序连接到特定的URL。我有一个ConnectionWindow以及支持收集来自用户的信息,并调用命令连接到该地址的ConnectionViewModel。下一次应用程序启动时,我想重新连接到同一地址不提示用户。

Lets say my application connects to a specific URL. I have a ConnectionWindow and a ConnectionViewModel that support gathering this information from the user and invoking commands to connect to the address. The next time the application starts, I want to reconnect to this same address without prompting the user.

我的解决办法,到目前为止是创建一个ApplicationViewModel,提供了一个命令连接到特定的地址,该地址保存到一些持久性存储器(它实际上是保存没有意义这个问题)。下面是一个简化的类模型。

My solution so far is to create an ApplicationViewModel that provides a command to connect to a specific address and to save that address to some persistent storage (where it's actually saved is irrelevant for this question). Below is an abbreviated class model.

应用程序视图模型:

public class ApplicationViewModel : INotifyPropertyChanged
{
    public Uri Address{ get; set; }
    public void ConnectTo( Uri address )
    { 
        // Connect to the address
        // Save the addres in persistent storage for later re-use
        Address = address;
    }

    ...
}

连接视图模型:

The connection view model:

public class ConnectionViewModel : INotifyPropertyChanged
{
    private ApplicationViewModel _appModel;
    public ConnectionViewModel( ApplicationViewModel model )
    { 
        _appModel = model; 
    }

    public ICommand ConnectCmd
    {
        get
        {
        	if( _connectCmd == null )
        	{
        		_connectCmd = new LambdaCommand(
        			p => _appModel.ConnectTo( Address ),
        			p => Address != null
        			);
        	}
        	return _connectCmd;
        }
    }    

    public Uri Address{ get; set; }

    ...
}

所以,问题是这样的:是一个ApplicationViewModel正确的方式来处理呢?否则怎么可能你存储应用程序的状态?

So the question is this: Is an ApplicationViewModel the right way to handle this? How else might you store application state?

编辑:我想也知道这如何影响可测试性。其中一个主要的理由使用MVVM是测试模式没有主机应用程序的能力。特别是我在应用程序设置是如何集中影响的可测性,并模拟出的相关模型的能力感兴趣的洞察力。

I'd like to know also how this affects testability. One of the primary reasons for using MVVM is the ability to test the models without a host application. Specifically I'm interested in insight on how centralized app settings affect testability and the ability to mock out the dependent models.

推荐答案

如果你没有使用MV-VM,解决方法很简单:你把这个数据和功能在你的应用派生类型。 Application.Current然后,您可以访问它。这里的问题,如你所知,是Application.Current导致当机测试视图模型的问题。这就是需要修复。第一步是从混凝土中的应用实例解耦自己。通过定义一个接口,并在您的具体应用类型实现它做到这一点。

If you weren't using M-V-VM, the solution is simple: you put this data and functionality in your Application derived type. Application.Current then gives you access to it. The problem here, as you're aware, is that Application.Current causes problems when unit testing the ViewModel. That's what needs to be fixed. The first step is to decouple ourselves from a concrete Application instance. Do this by defining an interface and implementing it on your concrete Application type.

public interface IApplication
{
  Uri Address{ get; set; }
  void ConnectTo(Uri address);
}

public class App : Application, IApplication
{
  // code removed for brevity
}

现在,下一步是消除视图模型中调用Application.Current通过使用控制或服务定位器反转。

Now the next step is to eliminate the call to Application.Current within the ViewModel by using Inversion of Control or Service Locator.

public class ConnectionViewModel : INotifyPropertyChanged
{
  public ConnectionViewModel(IApplication application)
  {
    //...
  }

  //...
}

所有的全球性的功能,现在通过mockable服务接口,IApplication提供。你还是留下了如何构建与正确的服务实例视图模型,但它听起来像你已经处理了吗?如果你正在寻找一个解决方案,在那里,玛瑙(声明,我是作者)可以提供解决方案在那里。您的应用程序将订阅View.Created事件,并添加自己作为一个服务,该框架将处理其余部分。

All of the "global" functionality is now provided through a mockable service interface, IApplication. You're still left with how to construct the ViewModel with the correct service instance, but it sounds like you're already handling that? If you're looking for a solution there, Onyx (disclaimer, I'm the author) can provide a solution there. Your Application would subscribe to the View.Created event and add itself as a service and the framework would deal with the rest.

这篇关于凡存储在MVVM应用程序设置/状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆