繁体   English   中英

通过 EFCore 3 中的接口解析 DbContext

[英]Resolve DbContext by Interface in EFCore 3

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


语境:

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

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

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

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

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()

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 ,我不明白为什么

正如/u/AngularBeginner所指出的:

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

你可以让你的IDbContext瞬态的(如果你可以接受的话)。

或者,您可以尝试使用CreateScope()方法创建一个临时作用域,然后从该新作用域提供程序获取您的 IMyService。

来源

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM