【问题标题】:Where should I convert my entities to DTO's?我应该在哪里将我的实体转换为 DTO?
【发布时间】:2012-07-09 05:29:48
【问题描述】:

我的架构如下所示:

    • 实体
    • 接口
    • DTO
  • 基础设施
    • ORM
    • 存储库
  • 服务
    • 网络服务

我想使用 AutoMapper 来转换它。我希望我的服务层只知道 DTO,所以我猜我的接口和存储库会返回转换后的 DTO。至于另一个方向,我会假设我的存储库将采用 DTO 并转换为实体?我是在正确的路径上还是在左侧?

【问题讨论】:

  • 谁将使用您的服务以及如何使用?
  • 我的服务将像 API 一样被访问到我的内部系统。有些将在内部,但在未来,外部系统将连接
  • 如果它在路上或内部,服务很容易连接和入侵,你暴露的端点(网络服务)应该返回安全的 DTO,它不会包含整个实体。
  • 所以也许正确的解决方案是映射到我的服务层的 DTO,但在我的存储库中,映射到 ViewModels
  • 是的,服务总是返回 DTO,因为我们将仅根据身份验证和用户访问权限发送信息。但是,我们使用动态序列化来避免 DTO 制作,这很痛苦。动态序列化仅根据登录的用户序列化实体的一部分,这些规则是在数据库本身编码和在代码外编码的。

标签: c# domain-driven-design


【解决方案1】:
  1. 您的存储库应该只处理围绕行为和事务设计的域聚合。

  2. 在处理命令时,您的应用层(Web 服务)应调用域模型上的逻辑,将聚合保存回存储库。

  3. 当客户端需要来自网络服务的数据时,您有两种选择:

    • 从存储库中获取聚合并将它们映射到 POCO DTO(可能使用 AutoMapper)。
    • 创建专门用于直接向 DTO 查询数据的精简数据访问层。

后一种方法是我的偏好。正如我所说,域聚合应该由行为和交易来设计。它们不是为在屏幕上显示数据而设计的。尝试将数据从正确设计的域实体(即正确封装)映射到数据消费者(例如 UI)的 DTO 始终是一个尴尬的过程。它是圆孔中的方形钉。在我看来,提供一个简单的数据访问层来返回客户端所需的任何数据要容易得多。域模型不需要参与这个过程;这只是数据。这就是CQRS的基本原理。

在任何情况下,它都应该是应用层(Web 服务)将域实体转换为 DTO。

【讨论】:

  • 这对我来说似乎是最好的方法。谢谢!
【解决方案2】:

您的服务层应该返回实体,而您的表示层(控制器驻留恕我直言)应该将实体转换为映射到您的用户界面(DTO)的对象。当然,这也意味着您的存储库将返回正常实体。

不要忘记只创建一次映射。创建一个引导程序或创建所有映射的东西,然后您只需在控制器中调用 Mapper.Map()。

【讨论】:

  • 是的。您应该使用您的实体(我想代表您的模型)直到您的最后一个 受控 层。
  • 那是我的问题,我的实体使用 Iesi.Collections.ISet 无法为我的服务层 WCF 服务序列化。我明白你的意思,但是对于我的 WCF 服务层,这会改变吗?
  • 不同意,除非他的架构保证实体遵循领域模型而不是数据模型。
  • 我正在尝试遵循域优先方法。
  • 如果你先做域然后你就不需要 DTO,你需要视图模型并且那些应该映射到你的接口层,在你的例子中是服务层,所以我同意 Leon .
猜你喜欢
  • 2011-01-27
  • 2022-09-30
  • 2019-07-11
  • 2016-05-25
  • 2017-04-04
  • 1970-01-01
  • 2012-08-06
  • 2020-01-01
  • 1970-01-01
相关资源
最近更新 更多