WCF DataContracts 和基础数据结构

Posted

技术标签:

【中文标题】WCF DataContracts 和基础数据结构【英文标题】:WCF DataContracts and underlying data structures 【发布时间】:2010-09-10 03:53:08 【问题描述】:

我想知道通过 WCF 服务公开哪些对象有意义 - 我应该将 WCF 序列化规范添加到我的业务实体,还是应该实现一个转换器,将我的业务实体映射到我想要公开的 DataContract通过我的 WCF 服务?

现在我有不同级别的实体:DataAccess、Business 和 Contract。我有转换器可以将实体从 DataAccess 映射到 Business,从 Business 映射到 Contract,反之亦然。实施和维护这些非常耗时且非常乏味。与此相关的最佳实践是什么?

如果我使用的是 NHibernate 或实体框架等 OR/M,我应该直接从 ORM 中公开实体,还是应该像现在一样抽象它们?

【问题讨论】:

【参考方案1】:

还有一点需要考虑,我同意这种分离,但它通常会导致“翻译器”或一些这样的代码将数据从 DTO 复制到业务实体。这就是像 AutoMapper (http://automapper.org/) 这样的库真正派上用场的地方,并且无需编写翻译层。

【讨论】:

【参考方案2】:

只是添加到上述答案: Web 服务公开的对象称为数据传输对象 (DTO)。拥有一个 DTO 来映射您的业务实体对象 (BEO) 是很好的,因为它在您的 Web 服务和 Web 服务背后的实际实现/逻辑之间提供了分离。

最后,您可以通过以下方式装饰 DTO,以便当它被 WSDL 公开时,名称会反映它所代表的实际对象(而不是 objectNameDTO 或类似的丑陋的东西)。

//Business Entity
class Person

   public string Name get; set; 
   public int Age get; set; 



//Data transfer object
[DataContract(Name="Person")] //<-- this is what makes the WSDL look nice and clean
class PersonDTO

   [DataMember(Name = "Name", Order = 0)]
   public string Name get; set; 
   [DataMember(Name = "Age", Order = 1)]
   public int Age get; set; 

【讨论】:

【参考方案3】:

我通常不会通过网络公开我的业务/数据实体,因为我喜欢遵守单一责任原则 (srp)。为了解释,创建数据实体以映射到底层关系 (db) 模型。所以他们应该“改变”的唯一原因是关系模型的改变,就是这样。

当您暴露这些实体以便它们可以越线时,它们有两个目的。这可能看起来有点矫枉过正,但它让事情变得更干净和透明......这会产生更简单的设计。

【讨论】:

【参考方案4】:

总的来说,我认为从最佳实践的角度来看,您不应该将业务对象的结构公开为数据合同,而是定义“特定于数据合同的”类并将业务转换为合同。它可能需要额外的工作,但从关注点分离和保护变化的角度来看,额外的工作可能是值得的。

Microsoft patterns & practices "Service Factory Modeling Edition" 实现了这一点,还提供了自动生成业务 合同转换器类的工具——它是一个出色的 VS 插件,也代表了 Microsoft 的 WCF 最佳实践。

【讨论】:

以上是关于WCF DataContracts 和基础数据结构的主要内容,如果未能解决你的问题,请参考以下文章

将 DataMember 添加到 WCF 中的现有 DataContract

如何在 WCF 测试客户端 (WcfTestClient.exe) 中指定列表参数?

何时/为啥不应该在我的 DataContracts 上使用 IsReference=true?

为啥 .Net 4.0 构建客户端 DataContracts 会导致 .Net 4.5 应用程序中的 MethodAccessException?

WCF基础

WCF基础:绑定