依赖注入,EF Core + Web API 2体系结构

时间:2018-07-23 16:21:40

标签: entity-framework sqlite asp.net-core-webapi asp.net-core-2.1 ef-core-2.1

我的布局

project.web (.net core 2.1 Web API)

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

project.api (类库)

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

project.core (类库)

两种服务

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

2)必须执行长期任务的服务(即:扫描文件夹,处理文件信息等)。实际上,我为这些主机创建了HostedServices,因为一个文件夹可以轻松地包含数千个文件。

project.store (类库)

用于存储的包装程序服务(仅包含辅助方法,因此我不必写相同的查询一百次。)

问题/问题

目前,我已将所有服务和存储库注册为public void ConfigureServices(IServiceCollection services)中的单例。 因为我在将代码重构为EF(sqllite)之前使用了其他存储(nosql,litedb)

现在的问题是我想将我的DbContext注册为作用域(默认情况下) 但是我的存储库(单例)取决于dbcontext。这意味着我也必须将这些范围定为范围。我可以接受,因为这些只是包装器服务,因此我不必一直写相同的查询。

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

我可以想到两种解决方案

第一个解决方案是对存储库中的 IServiceScopeFactory 建立依赖关系,并使用类似using (var scope = ServiceScopeFactory.CreateScope()) { scope.ServiceProvider.GetService(typeof(MyDbContext))... }

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

另一种解决方案是注册我所有仅处理范围内的数据库内容的服务。 (核心中的IE customerSservice仅进行验证并调用customerRepository)我从其余的单例服务中删除了依赖项。 在这些单例中,我可以不依赖于customersService,而可以将rest电话与restsharp或类似的东西一起使用

就像我将如何从Windows客户端应用程序和Web客户端应用程序中消费它们一样。

我实际上都不喜欢。但是有人可以给我一些建议或想法吗?

1 个答案:

答案 0 :(得分:1)

嗯,您列出的两个选项实际上只是您的两个选项。第一个是服务定位器反模式,顾名思义,您应该避免这种情况。但是,当您处理需要访问其他作用域中的对象的单例作用域对象时,没有其他方法。

唯一的选择是从单例中减少服务范围,这样您就可以直接注入上下文。并非所有内容都必须是单例。通常,如果您需要利用DbContext之类的东西,则有一个很强的论点是,您的对象首先应该是单例范围。如果您需要将其设置为单例作用域,则最有可能表明该类要么做得太多,要么变得脆弱。