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



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

到目前为止,我为架构考虑了类似的东西:

  • "全局"模型层,实现验证、研究标准、INotifyPropertyChanged和服务合同
  • 一些服务层,主要是针对实体框架4的服务层,实现了模型层的契约,并允许我访问和操作数据
  • 请注意,我还希望有一个离线数据源,比如XML或其他东西,从而获得另一个服务(我计划使用一些DI/IoC)
  • WCF层
  • 数据存储客户端的额外层
  • ViewModel

我对Views/ViewModel部分很清楚,但我很难弄清楚模型、WCF和ViewModel之间的关系。

我的问题是:

  1. 我应该如何处理EF生成的模型?扔掉它,走吧对于代码优先的方法,使用数据库
  2. 对于WCF数据传输,我是否应该属性,即产品有一个Customer而不是客户ID
  3. 我是否应该在WCF和ViewModel,用于存储和操作数据,还是最好的直接将ViewModel插入WCF的实践

欢迎为这种架构提供任何其他提示。。。

三层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之间添加额外的层可能被认为是过度工程。IMHO可以直接从ViewModel调用WCF服务。WCF生成的客户端代理代码具有模型的实际角色(至少是模型的一部分)。


编辑:

为什么MyProduct应该引用CustomerName而不是客户。在我的情况下,客户会有很多我愿意工作的房产具有这个"映射"不是太贵了吗?

您可以使用实际实体。但在客户端,由于它是一个三层架构,您无法通过导航属性访问数据库。如果有一个嵌套的Customer属性(类型为Customer),那么客户端将可以访问theProduct.Customer.Products,这是没有意义的。您不能以这种方式延迟加载实体(客户端没有DB上下文)。

扁平的"中间"POCO要简单得多。没有性能问题,映射很简单,与DB请求时间相比,该特定操作的CPU使用量非常小。

首先,一些一般信息:在Lab49 上有一个由Jason Dollinger编写的关于MVVM的非常好的教程

编辑视频涵盖了构建WPF应用程序时的大部分需求。依赖项注入和到WCF的连接也包括在内(但是在谈论WCF时没有深入,但用了一种非常有力的方式在这里提出好的解决方案)

他开发的源代码也可以在这里获得

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

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

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

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

别把模型搞砸了!生产是订单的一部分,订单有一个客户id。坚持这个。在您的服务层中,您可能最终会得到id。因为你可能不会在这里更改产品或客户。如果你这样做(和我订单示例不适合),您可以传输动态数据,而不是静态数据。

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

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

编辑如果必须调度服务层事件,那么WCF和ViewModel之间的轻量级小层。只要你有到,你可能会自然而然地想出这样一层。

最新更新