WPF MVVM WCF客户端/服务器体系结构

时间:2012-07-11 12:42:17

标签: wpf wcf architecture mvvm

我想构建一个基本的wpf / mvvm应用程序,它从带有WCF的服务器获取数据,并允许客户端显示/操作(使用CRUD操作)这些数据。

到目前为止,我考虑过类似的架构:

  • “全局”模型层,实现验证,研究标准,以及INotifyPropertyChanged和服务合同
  • 一些服务层,主要是一个用于实体框架4,实现模型层的契约并允许我访问和操作数据。
  • 请注意,我想要一个离线数据源,比如XML或其他东西,以及另一个服务(我打算使用一些DI / IoC)
  • WCF层
  • 数据存储客户端的额外层?
  • ViewModel

我对Views / ViewModel部分很清楚,但是我很难搞清楚模型,WCF和视图模型之间的关系。

我的问题是:

  1. 我该如何处理EF生成的模型?摆脱它去吧 对于代码第一种方法,手动进行映射 数据库?
  2. 对于WCF数据传输,我应该有关系吗? 我的模型中的属性,即产品有客户而不是客户 顾客ID ?
  3. 我应该在WCF和之间有一个额外的层 ViewModel,用于存储和操作数据,或者它是最好的 练习直接将ViewModel插入WCF?
  4. 欢迎任何有关此类架构的其他提示......

2 个答案:

答案 0 :(得分:4)

3层WPF应用程序的体系结构有不同的解决方案,但这里有一种可能性:

1 + 2)一种解决方案是创建表示客户端应用程序实际需要的“中间”对象。 例如,如果您的应用程序需要显示有关产品的信息以及相关的客户名称,则可以构建以下对象:

public MyProduct
{
    // Properties of the product itself
    public int ProductID { get; set; }
    public string ProductName { get; set; }
    ...

    // Properties that come from the Customer entity
    public string CustomerName { get; set; }
}

然后,您可以公开一个无状态WCF服务,该服务从ID返回您的产品:

[ServiceContract]
MyProduct GetProductByID(int productID);

在应用程序的服务器端(即服务的实现),您可以通过EF查询数据库(每次调用一个上下文)返回MyProduct实例构建:

public MyProduct GetProductByID(int productID)
{
    using (DBContext ctx = new ....)
    {
        return from p in ctx.Products
            where p.ID == productID
            select new MyProduct
            {
                ProductID = p.ID,
                ProductName = p.Name,
                CustomerName = p.Customer.Name  // Inner join here
            };
    }
}

3)在WCF服务和ViewModel之间添加额外的层可能被视为过度工程。恕我直言,可以直接从ViewModel调用WCF服务。 WCF生成的客户端代理代码具有模型的实际角色(至少是模型的一部分)。


编辑:

  

为什么MyProduct应该引用CustomerName而不是   客户。在我的情况下,客户将拥有我工作的许多房产   用。这种“映射”不是太贵了吗?

您可以使用实际实体。但在客户端,由于它是3层体系结构,因此您无法通过导航属性访问数据库。如果存在嵌套的Customer属性(类型为Customer),则客户端可以访问theProduct.Customer.Products,这没有任何意义,您不能以这种方式延迟加载实体(无数据库)客户端的背景)。

扁平的“中间”POCO是更简单的IMO。没有性能问题,映射很简单,并且与DB请求时间相比,此特定操作的CPU使用率是无穷小的。

答案 1 :(得分:2)

首先,一些一般信息:Jason Dollinger有一个关于MVVM的非常好的教程available at Lab49

修改 该视频涵盖了构建WPF应用程序时的大部分需求。 还包括依赖注入和与WCF的连接(但是 在谈到WCF时,并没有深入,但有一个非常强大的方式 在这里提出好的解决方案)

他开发的源代码也是available here

在我看来,每个与MVVM有关的人都应该看到它!

  

=> 1.我该如何处理EF生成的模型?摆脱它并采用代码优先方法,手动与数据库进行映射?

AutoMapper可以在这里提供帮助。 Codeplex of AutoMapper 你的问题似乎非常适合这个!

  

=> 2.对于WCF数据传输,我的模型中是否应该有关系属性,即Product有Customer而不是CustomerId?

不要乱用模特! productid是订单的一部分,订单具有客户ID。 坚持这一点。在您的服务层中,您最终可能会得到ID。 既然你可能不会在这里改变产品或客户。如果你这样做(和我的 订单示例不适合),您可以传输动态数据,而不是静态数据。

  

=> 3.我应该在WCF和ViewModel之间有一个额外的层来存储和操作数据,还是将ViewModel直接插入WCF的最佳做法?

在大多数情况下,我有一个服务层,在构造函数中将注入到我的viewmodel中。 这可以假设为另一层,因为它处理WCF客户端部分和 处理服务器端的“已更改”事件。 (行已更改,新行,行已删除等)

修改 如果您必须分派服务层事件,则更容易 WCF和ViewModel之间的那个小的,轻量级的层。只要你有 你可能会自然而然地想出这样一层。