我可以 Return 来自 DAL 的 DTO

Can I Return DTOs From DAL

我开始使用洋葱架构,因为我对以前的项目结构不满意。我的主要问题是,我可以 return 来自数据访问层的 DTO 吗?

这是我当前的结构:

/Core
 - Application
 - Domain
/Infrastructure
 - Persistence
 - Identity
/WebApi
 - WebApi

快速解释:

数据流如下:

Client <- WebApi Layer <- (DTO) Application Layer <- (Entity) Persistence Layer

截至目前,持久层 return 是在应用层转换为 DTO 的域层中定义的实际数据库实体。

我的问题是,持久层通常需要执行不同的查询,这会使类型与实体类型不同。例如,我可以连接不同的表、应用分组等。因此,我不能 return 实体类型。

我可以 return 来自持久层(数据访问层)的 DTO 吗?如果是,我在哪里定义这些 DTO?将它们与应用程序层中的其他 DTO 一起定义并在持久层中使用这些 DTO 将使其依赖于应用程序层(在我看来不太好,因为我们希望最小化耦合)。另一种选择是在域层中与实体一起创建它们(可能是更好的方法)?为了方便起见,我应该只从应用层 return DTO 还是 return 实体类型和 DTO 都可以吗?

很多我找不到的问题。只是想成为一个更好的程序员:)

My main question is, can I return DTOs from the data access layer?

是的。注意到:

  1. 是的,因为谁会阻止你?
  2. 是的,因为这是一种足够普遍的公认模式,一般来说,如果采用这种方法,小猫不会死。

Am I allowed to return DTOs from the persistence layer (data access layer)? If yes, where do I defined these DTOs?

我默认的“在没有理由不这样做的情况下”分层应用程序的体系结构是使用 DTO,我通常在公共库中定义它。 here (pdf) 的详细记录。数据访问、业务逻辑和 UI 都将此作为通用词汇共享。

这使得它们在您使用依赖注入抽象出数据访问的地方非常有用 - 您定义的接口也必须在其签名中使用 DTO。

如果您愿意,您可以定义只有数据访问层的 DTO,并且消费者知道它 - 问题是您为什么要这样做?并不是说你不能 - 只是说只有在你深思熟虑并且有有意义的理由去做的情况下你才应该这样做。

My problem here is that often, the persistence layer actually needs to perform different queries which will make the type different from the entity type. For example, I could join different tables, apply groupings, etc. Thus, I cannot return an entity type.

有时您会遇到您创建的 DTO 非常特定于场景的场景(不要重复使用)。只有你能说这是否可以接受。这是您要维护的代码量与 DTO 的适用性之间的权衡。我不认为具有场景特定的 DTO 本身是不好的,如果这意味着架构保持干净并且您实现场景的方式是明智的。