WCF DataContracts和基础数据结构

WCF DataContracts和基础数据结构

WCF DataContracts and underlying data structures

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

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

如果我使用的是诸如NHibernate或Entity Framework之类的OR / M,我应该直接从ORM中公开这些实体,还是应该以与现在相同的方式对其进行抽象?


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

Microsoft模式和实践" Service Factory建模版"实现了这一点,还提供了自动生成Business <=> Contract Converter类的工具-它是一个出色的VS加载项,并且代表了Microsoft的WCF最佳实践。


由于我喜欢遵守单一责任原则(srp),因此通常不会在网上公开我的业务/数据实体。为了说明,创建了数据实体以映射到基础关系(db)模型。因此,他们应该"更改"的唯一原因是由于关系模型的更改而已。

当您暴露这样的实体以便它们可以越过导线的那一刻,它们有两个作用。看起来似乎有些过激,但可以使事情保持清洁和透明……这可以简化设计。


我也同意一些考虑,但我同意这种分离,但通常会导致"翻译器"或某些类似的代码将数据从DTO复制到业务实体。在这里,像AutoMapper(http://automapper.org/)这样的库就可以派上用场了,并且无需编写翻译层。


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

最后,这里是装饰DTO的方法,以便当WSDL公开DTO时,名称将反映其代表的实际对象(而不是objectNameDTO或类似的东西)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//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; }
}


推荐阅读