应用程序的哪一层应该包含DTO实现
Which layer of the application should contain DTO implementation
最近我听到了很多关于 DTO 及其用途的消息,但我找不到在 ASP.NET 上下文中使用它的好例子。
假设我使用三层架构:
- 数据层(使用Entity Framework)
- 业务层(WCF 服务)
- 表示层(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 的项目,特别是与所有图层共享对象。无论名称如何,它都应该被所有层看到。
最近我听到了很多关于 DTO 及其用途的消息,但我找不到在 ASP.NET 上下文中使用它的好例子。
假设我使用三层架构:
- 数据层(使用Entity Framework)
- 业务层(WCF 服务)
- 表示层(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 的项目,特别是与所有图层共享对象。无论名称如何,它都应该被所有层看到。