应用程序的哪一层应该包含DTO实现

Which layer of the application should contain DTO implementation

最近我听到了很多关于 DTO 及其用途的消息,但我找不到在 ASP.NET 上下文中使用它的好例子。

假设我使用三层架构:

  1. 数据层(使用Entity Framework)
  2. 业务层(WCF 服务)
  3. 表示层(MVC 4.0 网络应用程序)

我应该在哪里将 EF Employee 对象转换为 EmployeeDTO POCO?

假设我在数据访问层进行了转换,但在 WCF 服务中发生了什么?然后它是否应该转换为另一个 DataMember 对象,当它到达 UI 层(MVC 网络应用程序)时是否应该第三次转换为模型?如果有人能帮我解决这个问题,我将不胜感激

查看此处添加的 ,因为我没有足够的声誉来添加评论。

就我个人而言,我会在持久层和业务层之间传递实体。当您使用 MVC 时,您很可能会将视图模型传递给您的控制器。届时我会将您的视图模型映射到您的 DTO。

如果您计划在所有层之间使用 DTO,请创建一个横切项目,然后您可以参考该项目。

我特别喜欢的一种方法是在您的业务层中进行 DTO 转换。

场景:您的表示层通过 DTO 调用您的业务层。您执行一些逻辑和验证,然后将 DTO 转换为实体并将其发送到您的数据访问层。

UI --> 总线。层(转换为实体)--> 数据层

我喜欢这种方法,因为我认为数据层不应该有任何转换逻辑,并且应该根据需要接收和处理实体。另一个有效的原因是您现在可以在转换过程中定义特定的业务规则/验证逻辑,然后再将其发送到数据层。 这是一个旧的 MSDN article,但有一些很好的细节解释了类似的方法。

在类似的情况下,我曾经将 dto 放入三个人都知道的 Core 中。所以你有

     Core
       |
 ------------
 |     |    |
DAL   BL   PL

每一层可以操作Core.Dto.Employee。每层还在其 API 中向外暴露 Core.Dto.Employee。但在内部每一层都可以 transform/adapt Core.Dto.Employee,例如您从数据库 EF.Employee 中读取,然后将其转换为 Core.Dto.Employee。变换包含在层的边界内。

如果你有几个不同的模型来表示整个层中的同一事物,例如 PL 想要 PL.Employee 而 DAL 在 EF.Employee 上运行,你最终会变得一团糟。

不应该有任何转换。您只需将 Poco 对象用作 DTO。

EF 与 Poco 一起工作,它们可以被 WCF 序列化。

它们应该在所有项目引用的程序集中定义。

在 ASP.NET MVC 中,您将使用 Poco - DTO 映射到 ViewModel。

您的服务层公开了 DTO。这意味着在服务层中,您可以按照您希望它们向外界公开的方式定义数据契约。在大多数情况下,它们是扁平实体,不一定与您的数据库实体具有相同的结构。

您的服务层有责任使用 business/data 层并构建您向外界公开的 DTO。

您在业务和数据层中使用的内容取决于架构。您可以首先使用代码映射域模型。在这种情况下,服务层将域实体映射到数据契约 (DTO)。如果您没有域模型(贫血模型),那么您也可以直接将数据库映射到您的 DTO。

ASP.NET MVC 站点使用该服务,并将它接收到的 DTO 映射到专用视图模型,然后将其传递给特定视图。

此外,您还可以决定将查询与命令分开。这是一个很好的方法,因为您作为查询的结果返回的 DTO 与您发送给服务的命令完全不同。命令只包含执行命令所需的内容,包含业务意图你想要实现的内容,而查询 returns 是你需要的扁平化模型 UI.

其他备注:

  • 不要公开您的数据库实体。
  • 不要在业务层转换,因为它不是业务逻辑。

我为此目的使用名为 Shared 的项目,特别是与所有图层共享对象。无论名称如何,它都应该被所有层看到。