将实体框架模型放置在洋葱架构的基础设施层中

时间:2020-12-28 07:58:48

标签: dependency-injection entity-framework-core domain-driven-design onion-architecture

我在 .NET Core 5 中使用 DDD 和 Onion 架构构建了一个 Web 应用程序。

有4层:

  1. 领域层 - 包含领域模型
  2. 应用层 - 具有核心业务逻辑并引用领域层
  3. 基础设施层 - 使用 EF Core 检索数据并将其保存到 Azure SQL,它指的是应用层
  4. API 层 - 具有控制器并指应用程序和基础设施层

通过API层引用基础设施层只是为了连接数据库,任何对数据库的请求都会通过应用层;应用层具有在基础设施层实现的接口,用于保存和检索数据库中的数据。

现在,当我使用代码优先或数据库优先的方法创建数据库时,这些 EF 模型类应该去哪里?

将它们放在域层会破坏洋葱架构,因为域层不应该了解基础设施层的任何信息。

  1. 在领域层中放置模型和映射

我见过几个示例,其中模型和映射放置在域模型中,而这些映射用于基础结构层 OnModelCreating(..),但特定于数据库的基础结构层映射仍然存在于域层中。如果我想用其他数据库替换基础架构层,在这种情况下我需要更改对我来说似乎不合适的域模型,该怎么办..

  1. 在基础设施层放置模型

我可以在基础设施层放置 EF 模型类,但如何在应用层中引用它们?我是否需要为每个模型存储库提供一个接口,或者同一个接口是否存在多个依赖项注入?

我希望域模型由业务模型保存,并将 EF 模型放置在基础设施层,并在必要时使用 AutoMapper 在它们之间进行映射。

那么保存 EF 模型的最佳实践是什么,这样它就不会破坏 Onion 架构。

2 个答案:

答案 0 :(得分:0)

好吧,您可以让基础设施层从 EF 核心检索数据并将其映射到域层,您必须为每个将返回域模型的存储库提供一个接口。对于同一接口的不同实现,您始终可以构建某种工厂来处理它。 类似 this 的答案。

答案 1 :(得分:0)

如果您使用的是 EF Core,我认为不需要单独的 EF 模型

我通常做的是在领域层中实现领域模型类,以最好的方式支持我的业务逻辑。然后在基础设施层中放置实体框架配置类,使用带有泛型的IEntityTypeConfiguration

这正是被认为是为了保持领域模型类不受基础设施问题的影响,这样即使您更改数据库实现,领域模型也永远不必更改。

您可以在由 Microsoft 提供支持的 EShopOnContainers 参考项目中看到一个工作示例 here

例如,Order 聚合定义在域层中,而 EF Core 的相应模型 configuration class 放置在基础结构层中。

然后一切都像往常一样在 API project startup 和基础结构层的相应 DbContext (OrderingContext) 类中连接起来。

基础设施层将依赖于域层中的域实体,而不是相反,这是您希望在洋葱架构中实现的目标。