WCF消息和数据契约,DTO,域模型,和共享组件(WCF Message & Data Contra

2019-06-26 13:50发布

我有一个Web客户端调用我的WCF业务服务层,这反过来,调用外部WCF服务,以获得实际的数据。 起初,我以为我会使用的DTO,并在不同的层独立商业实体......但我发现,倡导的DTO的简单的例子,是,好了,琐碎。 我看到太多重复的代码并没有太大的好处。

考虑我的域名:

例如结构域I有一个单一的UI画面(Asp.net MVC视图)示出药物的患者的列表,所述不良反应(药物之间),以及任何临床病症(如抑郁症或高血压)的患者可能具有。 我的域模型开始在与顶层:

   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请求时,我们有一个请求/响应对象,例如

   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和设计的分离,是我该做的吗?

   MedicationRecordResponseDto
      MedicationRecordDto
      List<ClientMessageDto> 
      QueryStatusDto

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

因为我有显示几乎所有的屏幕上的信息,我切实为我有每个域对象创建1 DTO。

我的问题是 - 你会怎么办? 你会继续前进,创造这一切的DTO? 或者,你只是分享您的域模型在单独的程序?

下面是这似乎其他相关问题,一些阅读:

  1. WCF契约知道域
  2. 在SOA转换层的替代品:WCF
  3. SOA问题:揭露实体

Answer 1:

就以优秀的文章一起来看看

  • 为什么你不应该暴露你的实体通过您的服务
  • DTO的应传输数据,而非机构

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

  • DTO的应传输数据,而非机构
  • 为什么你不应该暴露你的实体通过您的服务


Answer 2:

I've always had an aversion to the duplicate class hierarchy resulting from DTOs. It seems to be a flagrant violation of the DRY principle. However, upon closer examination, the DTO and the corresponding entity or entities serve different roles. If you are indeed applying domain-driven design then your domain entities consist of not only data but behavior. By contrast, DTOs only carry data and serve as an adapter between your domain and WCF. All of this makes even more sense in the context of a hexagonal architecture also called ports and adapters as well as the onion architecture. Your domain is at the core and WCF is a port which exposes your domain externally. A DTO is part of how WCF functions and if you agree that it is a necessary evil your problem shifts from attempting to eliminate them to embracing them and instead focusing on how to facilitate the mapping between DTOs and domain objects. A popular solution is AutoMapper which reduces the amount of boiler plate mapping code you need to write. Aside from the drawbacks, DTOs also bring a lot of benefits. One is that they furnish a buffer between your domain entities and the outside world. This can be of great help in refactoring because you can keep your core domain very well encapsulated. Another benefit is that you can design your DTOs such that they fulfill requirements of the service consumer, requirements which may not always be in full alignment with the shape of your domain objects.



Answer 3:

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

我已经使用这个服务的现有C#控制台应用程序客户端。 现在,我有一个新的要求。 我需要在实体添加一个新的领域。 这不是由客户需要。 新字段是仅适用于该服务的内部计算。 我不得不在MessageContract也作为一个实体添加一个名为“LDAPUserID”的新属性。

这可能会或可能不会打破依赖于客户端是否支持客户端Lax Versioning 。 请参阅服务版本 。

人们很容易误认为是增加一个新成员不会破坏现有的客户端。 如果你不确定是否所有的客户端可以处理不严版本中,建议使用严格的版本控制指导原则和数据处理的合同不变。

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

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

设计改造对象的业务实体和数据合约之间的转换。

参考文献:

  1. 如何序列化的NHibernate的映射对象的所有属性?
  2. 使用WCF类库暴露对象
  3. 序列化属性的子集,只


文章来源: WCF Message & Data Contract, DTO, domain model, and shared assemblies