依赖注入,EF Core + web api 2 架构

Dependency Injection, EF Core + web api 2 architecture

我的布局

project.web (.net core 2.1 web api)

一些绑定模型(对于post/put请求)和资源模型对于GET请求 控制器。 我 只调用来自 (x.api) 的接口,这些接口被解析为 x.core 服务。 没有验证或任何东西。这发生在核心层内部 我已经设置了一些与我的问题无关的东西,比如 automapper 和 swagger。

project.api(class 库)

仅包含 .core 和 .store 项目(服务、存储库和领域模型)的接口

project.core(class 库)

两种服务

1) 调用存储库服务(接口)的服务。但在调用回购服务之前验证数据。

2) 必须执行长期任务的服务(即:扫描文件夹、处理文件信息,...)。我实际上为这些创建了 HostedServices,因为一个文件夹很容易包含数千个文件。

project.store(class 库)

我的存储包装服务(只包含辅助方法,所以我不必将相同的查询写一百遍。)

问题/问题

此时我已经在 public void ConfigureServices(IServiceCollection services) 中将我所有的服务和存储库注册为单例 因为在将代码重构为 EF (sqllite)

之前,我使用了不同的存储(nosql、litedb)

现在的问题是我想将我的 DbContext 注册为作用域(默认情况下) 但是我的存储库(单例)依赖于 dbcontext。这意味着我也必须将这些设置为范围。我对此没有意见,因为这些只是包装服务,所以我不必一直编写相同的查询。

但是其他一些需要访问我的数据的服务是单例的,我无法将它们注册为作用域。包含一些需要对每个请求都相同的数据,以及一些集合和长 运行 作业。

我能想到两个解决方案

第一个解决方案是在我的存储库中为 IServiceScopeFactory 创建一个 dependency 并使用类似 using (var scope = ServiceScopeFactory.CreateScope()) { scope.ServiceProvider.GetService(typeof(MyDbContext))... }

这样我可以从我的存储库包装器中删除依赖项,但这对我来说听起来不太干净。

另一个解决方案是将我所有只处理数据库内容的服务注册为范围。 (核心中的 IE customerSservice 仅进行验证并调用 customerRepository)我从剩余的单例服务中删除了依赖项。 在那些单身人士中,我可以使用带有 restsharp 或类似东西的休息调用,而不是依赖于 customersService

就像我从 windows 客户端应用程序和 Web 客户端应用程序中使用它们一样。

其实我也不喜欢。但是也许有人可以给我一些建议或想法?

好吧,您列出的两个选项实际上是您仅有的两个选项。第一个是服务定位器反模式,顾名思义,您应该避免这种模式。但是,当您处理需要访问其他范围中的对象的单例范围对象时,别无他法。

唯一的其他选择是减少单例服务的范围,这样您就可以直接注入上下文。并不是所有的东西都必须是单身人士。通常,如果您需要使用 DbContext 之类的东西,那么您的对象首先应该 而不是 是单例范围的,这是一个强有力的论据。如果你需要它是单例范围的,这很可能表明 class 要么做得太多,要么在其他方面很脆弱。