【问题标题】:Where to consume webservices in MVVM?在 MVVM 中哪里可以使用 Web 服务?
【发布时间】:2013-01-30 20:23:39
【问题描述】:

使用 Visual Studio 2012,我添加了对远程 Web 服务的服务引用。它被配置为使用异步调用。该应用程序使用带有 MVVM 模式的 WPF。

一个模型类称为Projects,它公开了一个属性ProjectList,可以在视图模型中使用。 ProjectList 应包含从服务中检索到的项目列表。

到目前为止,我像这样从视图模型中调用此服务(实际上它是由命令调用的):

Projects.ProjectList = proxy.getProjectList(username, password);

是的,它有效,但据我所知,“业务逻辑”不应该由视图模型处理。那么当视图在视图模型中触发命令时,我将如何以及在何处调用服务并设置模型的 ProjectList 属性?

【问题讨论】:

  • 我通常把它放到一个它自己的类中,用来处理数据事务,然后使用 ViewModel 中的那个类。这样,如果我的数据层发生变化,我只需要修改一个层,而不是在我的所有 ViewModel 中搜索需要更新的数据访问代码。
  • @Rachel:是的,这也是我的理解,但是数据层——或者任何可能称之为的——会直接修改模型属性吗?还是视图模型会设置它?
  • 数据层返回的是模型对象,而不是模型的数据。所以IProductsRepository.GetProducts() 会返回一个List<Product> :)

标签: c# wpf wcf mvvm


【解决方案1】:

使用依赖注入将多态接口传入您的 ViewModel。

在此接口中定义将与您的 Web 服务通信并在具体对象中实现此接口的函数。根据您需要访问的服务源实例化您需要的具体对象,并通过您定义的接口将其传递给 ViewModel。

这样您就可以轻松实现松耦合和多态的所有好处...

例如:

public ProjectListViewModel(IProjectListServiceAgent sa)

public interface IProjectListServiceAgent
{
    GetProjectList(string userName, string password)
}


public SqlProjectListFetcher : IProjectListServiceAgent 
{
   GetProjectList(string userName, string password)
   {
       //Fetch project list using direct SQL server access.
   }
}

public WebServiceProjectListFetcher : IProjectListServiceAgent 
{
   GetProjectList(string userName, string password)
   {
       //Fetch project list using web service.
   }
}

【讨论】:

    【解决方案2】:

    将依赖项传递给 ViewModel 以使用代理,我更喜欢始终使用异步系统的同步代码,因此代理具有方法 proxy.GetCustomerList,您可以使用 async 关键字或 TaskFactory。

    我正在为 MVVM 维护一个小框架助手来简化这项任务,特别是:

    1. 检索 DTO、单个或列表
    2. 使用自定义映射器(也包括 AutoMapper)转换为 ViewModel
    3. [可选] 对列表进行排序
    4. [可选] 完成后执行方法

    也可以在单个线程中执行所有内容以更改配置以进行测试

    源代码(不是实时更新)在这里http://hyperionsdk.codeplex.com 和包在这里http://nuget.org/packages/EyeSoft.Wpf.Facilities

    用法示例:

    public ViewModelSorted(ServiceFactory<ICustomerService> customerServiceFactory)
    {
        customerServiceFactory
            .Collection(this, x => CustomerCollection)
            .Sort(x => x.LastName)
            .Fill(x => x.GetCustomersWithTurnoverGreatherThan(0));
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-05
      • 1970-01-01
      相关资源
      最近更新 更多