将DTO传递到服务层

MyT*_*tle 3 c# java design-patterns multi-tier three-tier

将DTO对象传递给服务层不是坏习惯吗?

现在,我的服务层方法如下所示:

public save(MyEntity entity);
Run Code Online (Sandbox Code Playgroud)

从DTO到业务实体(MyEntity)的值映射在表示层上完成

但是我想将方法​​签名更改为此:

public save(MyEntityDTO dto, String author);
Run Code Online (Sandbox Code Playgroud)

从DTO到业务实体的映射将在服务层上进行。

编辑:我想要它,因为从DTO映射到业务对象时需要打开休眠会话,因此实体上的所有更改都将自动刷新。

Rhu*_*arb 7

这是有争议的。(正如对已接受答案的评论中所证明的那样)一方面,DTO 属于处理数据传输的应用程序层显然是您的表示层。

另一方面,在服务层中正确处理的域对象(业务实体)可能具有属性 - 例如 Id、LastUpdated 等未传递到 save 方法的属性。那么你传入什么?好吧,您只传递您需要的属性。碰巧的是,对 save() 的请求 MyEntityDTO 恰好封装了所有且仅那些属性!...

所以你现在有一个不幸的选择:

  1. 从表示层传入业务对象

    (也破坏了分层模型,并强制您忽略 Id 和 LastUpdated 等属性,这些属性不在“请求”中)

  2. 将 DTO 分解为属性并将它们传入:

    service.save(Dto.Property_One, Dto.Property_Two)

    然后您必须在 save() 方法中将其重新组合在一起。

  3. 创建一些对象来封装 Property_One、Property_Two 等

  4. 接受 DTO 也用于层间传输

在我看来,这些都不是理想的,这就是为什么我认为#4 还可以。可能最正确的是#2 - 但同样..并不理想。

有时命名我可以减轻痛苦:“MyEntityRequest”而不是“DTO”


Lig*_*man 6

将DTO对象传递给服务层不是坏习惯吗?

您不仅可以将DTO对象传递给服务层,而且还应该将DTO对象而不是业务实体传递给服务层。

您的服务应该接收DTO,将它们映射到业务实体,然后将其发送到存储库。它还应从存储库中检索业务实体,将其映射到DTO,然后将DTO作为响应返回。因此,您的业务实体永远不会脱离业务层,只有DTO会这样做。

这里查看类似问题的完整答案。

  • 这个答案是如此错误,它表明 SO 可能会产生误导,并且不应将其视为不惜一切代价、在所有情况下唯一有效的开发人员资源。这是错误的。服务层不应该对 DTO 有任何了解,它是业务层,应该只处理业务。在控制器中,您应该处理 DTO。 (10认同)
  • 错误的答案。底层不应该知道架构顶层的层。他们应该有自己的api来提供内部层之间通信的能力。对于服务之间的通信,您将仅使用服务层对象,而不需要任何到控制器(客户端)级别 dto 的映射。对于控制器和服务之间的通信,您必须执行一些基本验证并映射到服务层对象,然后调用实际的服务方法。 (7认同)