代码之家  ›  专栏  ›  技术社区  ›  Hairydruidy

依赖注入,EF核心+Web API 2架构

  •  0
  • Hairydruidy  · 技术社区  · 6 年前

    我的布局

    项目.web (.NET核心2.1 Web API)

    一些 绑定模型 (用于邮寄/寄出请求)和 资源模型 获取请求 控制器。 我 仅从(x.api)调用接口 解决了X.core服务。 没有验证或其他。这发生在核心层内部 我已经设置了一些与我的问题无关的东西,比如automapper和swagger。

    项目.api (lib类)

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

    项目.core (lib类)

    两种服务

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

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

    项目.存储 (lib类)

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

    问题/问题

    此时,我已将所有服务和存储库注册为 public void ConfigureServices(IServiceCollection services) 因为在将代码重构为ef(sqllite)之前,我使用了不同的存储(nosql、litedb)。

    现在的问题是,我希望将dbContext注册为scoped(默认情况下) 但我的存储库(singleton)依赖于dbContext。这意味着我也要做这些范围。我同意这一点,因为这些只是包装服务,所以我不必一直编写相同的查询。

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

    我能想到两个解决办法

    第一个解决方案是 附属国 ISeviceScopeFactory公司 在我的存储库中使用 using (var scope = ServiceScopeFactory.CreateScope()) { scope.ServiceProvider.GetService(typeof(MyDbContext))... }

    通过这种方式,我可以从存储库包装器中删除依赖项,但这对我来说并不干净。

    另一个解决方案是注册所有只处理数据库内容的服务。(即核心中的customerservice只进行验证并调用customerrepository)我从剩余的singleton服务中删除依赖项。 在这些单打电话中,我可以使用restsharp或类似的电话,而不是依赖于客户服务。

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

    实际上我也不喜欢。但也许有人能给我一些建议或想法?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Chris Pratt    6 年前

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

    唯一的另一个选择是将服务的范围从单例减少,这样您就可以直接插入上下文。不是所有的事情都必须是单身。一般来说,如果你需要利用 DbContext 有一个强有力的论据认为你的对象应该 首先是单点作用域。如果您需要它是单例作用域的,那么这很可能表明该类要么做得太多,要么很脆弱。