首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WCF消息和数据契约、DTO、域模型和共享程序集

WCF消息和数据契约、DTO、域模型和共享程序集
EN

Stack Overflow用户
提问于 2012-07-27 04:32:07
回答 3查看 5.7K关注 0票数 5

我有一个web客户端,它调用我的WCF业务服务层,然后调用外部WCF服务来获取实际数据。一开始,我想我会使用DTO,在不同的层次上有独立的业务实体.但我发现,提倡DTO的琐碎例子是,嗯,微不足道的。我看到太多重复的代码,却没有多大的好处。

考虑一下我的领域:

例如,我有一个单一的UI屏幕(Asp.net MVC视图),它显示患者的药物列表、药物之间的不良反应以及患者可能出现的任何临床状况(如抑郁症或高血压)。我的域模型从顶层开始:

代码语言:javascript
复制
   MedicationRecord
      List<MedicationProfile> MedicationProfiles
      List<AdverseReactions> Reactions
      List<ClinicalConditions> ClinicalConditions

   MedicationProfile is itself a complex object
      string Name
      decimal Dosage
      Practitioner prescriber 

   Practioner is itself a complex object
      string FirstName
      string LastName
      PractionerType PractionerType
      PractionerId Id
      Address Address    

      etc.

此外,在发出WCF请求时,我们有一个请求/响应对象。

代码语言:javascript
复制
   MedicationRecordResponse
      MedicationRecord MedicationRecord
      List<ClientMessage> Messages
      QueryStatus Status

   and again, these other objects are complex objects
   (and further, complicates matter is that they exist in a different, common shared namespace)

在这一点上,我的倾向是MedicationRecordResponse是我的DTO。但是在纯DataContracts和DTO以及设计的分离中,我应该这样做吗?

代码语言:javascript
复制
   MedicationRecordResponseDto
      MedicationRecordDto
      List<ClientMessageDto> 
      QueryStatusDto

   and that would mean I then need to do
      MedicationProfileDto
      PractitionerDto
      PractitionerTypeDto
      AddressDto
   etc.

因为我已经在屏幕上显示了几乎所有的信息,所以我实际上为我拥有的每个域对象创建了一个DTO。

我的问题是.你会怎么做?你会继续创建所有这些DTO吗?或者您会在单独的程序集中共享域模型吗?

以下是一些似乎与此相关的其他问题:

  1. WCF合同知道域
  2. SOA中转换层的替代方案: WCF
  3. SOA问题:公开实体
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-07-27 05:39:49

看一看优秀文章

  • 为什么不通过服务公开实体
  • DTO应该传输数据,而不是实体

上面的链接不起作用,看起来像一个域问题(我希望它能被修复),这里是源代码:

票数 6
EN

Stack Overflow用户

发布于 2012-07-27 05:09:51

我一直不喜欢DTO造成的重复类层次结构。这似乎是对干的原则的公然违反。然而,经过更仔细的审查,DTO和相应的一个或多个实体发挥不同的作用。如果您确实在应用领域驱动的设计,那么您的领域实体不仅包括数据,还包括行为。相比之下,DTO只携带数据,并充当域和WCF之间的适配器。在六角形建筑 (也称为端口和适配器)以及洋葱结构的上下文中,所有这些都更有意义。您的域位于核心位置,WCF是对外公开您的域的端口。DTO是WCF功能的一部分,如果您同意它是必要的邪恶,那么您的问题就会从试图消除它们转移到拥抱它们,而专注于如何促进DTO和域对象之间的映射。一个流行的解决方案是AutoMapper,它减少了您需要编写的锅炉板映射代码的数量。除了缺点之外,DTO还带来了很多好处。一个是它们在您的域实体和外部世界之间提供了一个缓冲区。这对于重构非常有帮助,因为您可以很好地封装您的核心域。另一个好处是,您可以设计DTO以满足服务使用者的需求,这些需求可能并不总是与域对象的形状完全一致。

票数 3
EN

Stack Overflow用户

发布于 2013-04-05 08:04:19

就我个人而言,我不喜欢使用MessageContract作为实体。不幸的是,我有一个使用MessageContract作为实体的现有WCF服务--即数据被直接填充到数据访问层的MessageContract中。不涉及翻译层。

我有一个使用此服务的现有C#控制台应用程序客户端。现在,我有了新的要求。我需要在实体中添加一个新字段。这不是客户所需要的。新字段仅用于服务中的内部计算。我必须在LDAPUserID中添加一个名为“MessageContract”的新属性,它也是一个实体。

这可能会或不可能破坏客户端,这取决于客户端是否支持Lax Versioning。请参考服务版本化

很容易错误地认为添加一个新成员不会破坏现有的客户端。如果您不确定所有客户端是否能够处理松散的版本控制,则建议使用严格的版本控制指南,并将数据契约视为不可变。

有了这一经验,我认为使用MessageContract作为实体是不好的。

另外,请参考MSDN -服务层指南

设计在业务实体和数据契约之间转换的转换对象。

参考文献:

  1. 如何序列化NHibernate映射对象的所有属性?
  2. 使用WCF公开类库中的对象
  3. 仅序列化属性的子集
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11681475

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档