我在 .NET Core 5 中使用 DDD 和 Onion 架构构建了一个 Web 应用程序。
有4层:
通过API层引用基础设施层只是连接数据库,任何对数据库的请求都会经过应用层;应用程序层具有在基础设施层中实现的接口,用于保存和检索数据库中的数据。
现在,当我使用代码优先或数据库优先方法创建数据库时,这些 EF 模型类应该放在哪里?
将它们放在域层中会破坏洋葱架构,因为域层不应该了解基础设施层的任何信息。
我见过几个示例,其中模型和映射放置在域模型中,并且这些映射用于基础设施层
OnModelCreating(..)
,但特定于数据库的基础设施层映射仍然存在于域层中。如果我想用其他数据库替换基础设施层怎么办,在这种情况下我需要更改域模型,这对我来说似乎不合适..
我可以将EF模型类放在基础设施层,但是如何在应用层引用它们?我是否需要为每个模型存储库提供一个接口,或者同一接口是否有多个依赖注入?
我希望领域模型由业务模型保存,并将 EF 模型放置在基础设施层中,并在必要时使用 AutoMapper 在它们之间进行映射。
那么保存 EF 模型的最佳实践是什么,以免破坏 Onion 架构?
如果您使用 EF Core,我认为不需要单独的 EF 模型。
我通常做的是在域层中实现域模型类,它最好地支持我的业务逻辑。然后在基础设施层中,使用带有泛型的IEntityTypeConfiguration放置实体框架配置类。
这正是人们认为的使用方式,以便使域模型类不受基础设施问题的影响,这样即使您更改数据库实现,域模型也永远不必更改。
您可以在此处在 Microsoft 支持的 EShopOnContainers 参考项目中查看工作示例。
例如,Order聚合在域层中定义,而 EF Core 的相应模型配置类则放置在基础设施层中。
然后,在API项目启动和基础设施层中相应的DbContext(OrderingContext)类中,一切都像往常一样连接起来。
基础设施层将依赖于域层中的域实体,而不是相反,这正是您想要在洋葱架构中实现的目标。
您可以让基础设施层从 EF 核心检索数据并将其映射到域层,您必须为每个将返回域模型的存储库提供一个接口。至于同一接口的不同实现,您始终可以构建某种可以处理该问题的工厂。 像this这样的答案。