WCF DataContracts和底层数据结构

时间:2008-09-17 14:05:35

标签: wcf data-access

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

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

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

4 个答案:

答案 0 :(得分:12)

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

Microsoft patterns & practices "Service Factory Modeling Edition"实现了这一点,并提供了自动生成Business< =>的工具。合同转换器类 - 它是一个出色的VS插件,也代表了微软对WCF的最佳实践。

答案 1 :(得分:4)

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

当你暴露这些实体以便它们可以穿过电线时,那么它们就有两个目的。它可能看起来有点矫枉过正,但它可以保持清洁和透明......这样可以实现更简单的设计。

答案 2 :(得分:1)

只是添加上述答案: 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 :(得分:1)

还有一些事情要考虑,我同意这种分离,但它通常最终导致“翻译者”或一些此类代码将数据从DTO复制到业务实体。这就像AutoMapper(http://automapper.org/)这样的库真正方便,并且不需要编写转换层。