【问题标题】:Resolve DbContext by Interface in EFCore 3通过 EFCore 3 中的接口解析 DbContext
【发布时间】:2019-12-06 09:55:06
【问题描述】:

通过接口注册/解析 DbContext 的正确方法是什么?


上下文:

我有多个 Web 服务,每个服务都有不同的 dbcontext。

由于我需要在共享项目中编写一些通用功能,我编写了一个由每个 dbcontext 实现的接口,因此我可以拥有一组共享功能“dbcontext-implementation-agnostic”,只需注入 dbcontext 接口。

在每个项目中,每个 dbcontext已经被其实现使用和注入,但我想在 common features 项目中只使用它的接口。

所以,在每个网络服务中,我都会有类似的内容:

services.AddDbContext<IMyDbcontext, MyDbcontext>(options =>
{
    options.UseSqlServer(configuration.GetConnectionString("MyDbContext"));
});
services.AddTransient<ISharedService, SharedService>();

在共享项目中

public class SharedService : ISharedService
{
    public SharedService(IMydbcontext context)
    {
        [...]
    }

    [...]
}

拥有IMyDbcontext就像

public interface IMyDbcontext
{
    DbSet<SharedSettings> Settings { get; set; }

    int SaveChanges(bool acceptAllChangesOnSuccess);
    int SaveChanges();
    Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default);
    Task<int> SaveChangesAsync(CancellationToken cancellationToken = default);
}

我需要 Startup.cs 中的 ISharedService - Configure() with

app.ApplicationServices.GetService<ISharedService>();

我一直在谷歌上搜索并尝试了不同的方法,但我找不到一种有效的方法......

我尝试过使用转发器,如下所示:(建议here

services.AddDbContext<MyDbContext>();
services.AddScoped<IMyDbContext>(provider => provider.GetRequiredService<MyDbContext>());

但是,虽然我在解决具体的 MyDbContext 时没有问题,但每当我尝试解决 IMyDbContext 时都会收到此错误

System.InvalidOperationException: '无法解决 来自根提供商的“Blah.IMyService”,因为它 需要范围服务 'Blah.IMydbcontext'。'

其中IMyService 注册为瞬态,它的实现构造函数是

public MyService(IMydbcontext context)

我也试过这样注册dbcontext

services.AddDbContext<IMyDbContext, MyDbContext>();

但是,当我尝试解决 MyDbContext 时,我得到了 null,我不明白为什么

【问题讨论】:

  • 您能否展示一个更详细的当前启动示例以及相关类。目前尚不清楚您是否需要接口或实现。
  • 你想做什么?如果您想同时解析MyDbContextIMyDbContext,则必须注册这两种类型。 AddDbContext&lt;IMyDbContext, MyDbContext&gt; 仅注册 IMyDbContextMyDbContext 提供的实现。只需注册 MyDbContext 就足够了 - 任何需要 MyDbContext 的代码都会得到一个,并且永远不必知道数据来自哪里,例如数据库或字典。
  • 我添加了更多上下文

标签: c# dependency-injection .net-core dbcontext ef-core-3.0


【解决方案1】:

正如/u/AngularBeginner指出的那样:

IMyService 需要一个作用域 IMyDbContext,但在您的 启动 Configure() 方法,你没有范围。

您可以使您的 IDbContext 瞬态(如果这是可以接受的 你)。

或者,您可以尝试使用 CreateScope() 方法,然后从该新作用域中获取您的 IMyService 提供者。

Source

所以,我用 IServiceScopeFactory 创建了一个作用域,它成功了

var scopeFactory = app.ApplicationServices.GetService<IServiceScopeFactory>();   
using var scope = scopeFactory.CreateScope();
var myService = scope.ServiceProvider.GetService<IMyService>();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-07
    • 2017-09-17
    • 1970-01-01
    • 2021-05-06
    • 1970-01-01
    相关资源
    最近更新 更多