【问题标题】:Cannot inject DbContext in repository无法在存储库中注入 DbContext
【发布时间】:2019-08-17 18:54:09
【问题描述】:

我尝试为新的 ASP.NET Core 站点设置 DI,并且我有以下代码:

public void ConfigureServices(IServiceCollection services)
{
    services
        .AddMvc()
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

    // Get the configuration from the app settings.
    var config = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json")
        .Build();

    // Get app settings to configure things accordingly.
    var appSettings = Configuration.GetSection("AppSettings");
    var settings = new AppSettings();
    appSettings.Bind(settings);

    services
        .AddOptions()
        .Configure<AppSettings>(appSettings)
        .AddSingleton<IConfigurationRoot>(config)
        .AddDbContext<MyDbContext>(builder =>
        {
            builder.UseSqlServer(config.GetConnectionString("myConn"));
        }, ServiceLifetime.Transient, ServiceLifetime.Transient);

    services.AddSingleton<ILoadTestCleanUpServiceRepository, LoadTestCleanUpServiceRepository>();
        ...

现在,LoadTestCleanUpServiceRepository 依赖于 MyDbContext:

public class LoadTestCleanUpServiceRepository : ILoadTestCleanUpServiceRepository
{
    private readonly MyDbContext _dbContext;

    public LoadTestCleanUpServiceRepository(MyDbContext dbContext)
    {
        _dbContext = dbContext;
    }
    ...

..数据库上下文是这样的:

public class MyDbContext : DbContext
{
    public MyDbContext(DbContextOptions<MyDbContext> ctxOptions) : base(ctxOptions)
    {
    }
}

当我运行应用程序时,我得到这个错误:

InvalidOperationException:无法解析服务类型 'MyCode.Infrastructure.Common.MyDbContext' 尝试 启用 'MyCode.Infrastructure.LoadTestCleanUpService.LoadTestCleanUpServiceRepository'。

我已尝试更改 ServiceLifetime 选项并添加此额外代码:

services.AddTransient<MyDbContext>(sp => new MyDbContext(config));

...但似乎没有任何帮助,我不明白为什么这不起作用。它确实尝试构建存储库,但为什么它也不能构建 DB Context?它甚至没有达到我打电话给UseSqlServer()的地步! 有什么想法吗?

更新 1:

嗯...我现在看到了。很可能是相关的:

更新 2:

我现在有:

  • 将 EF 6 替换为 Microsoft.EntityFrameworkCore.SqlServer
  • 已升级到 netcoreapp2.2 目标框架以解决一些冲突的程序集版本。
  • 将存储库设为范围。

但我仍然遇到同样的错误。

【问题讨论】:

  • 为什么 MyDbContext 类有 AcDbContext 作为构造函数?这段代码可以编译吗?
  • @Dimitar 对不起。我现在已经解决了。我“更改”了代码名称的某些部分以避免泄露我的项目信息。这不是任何绝密的东西,但我尽量让代码“通用”。
  • 我遇到了类似的问题,是的,EF 版本不匹配是唯一的解释
  • 您不能在单例服务中使用作用域数据库上下文。试图使数据库上下文瞬态也不会解决这个问题。考虑让您的存储库自行限定范围。
  • 请注意,您的 MyDbContext 在 LoadTestCleanUpServiceRepository 中被俘虏为 Captive Dependency。

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


【解决方案1】:

我看到您已将LoadTestCleanUpServiceRepository 注册为Singleton 而MyDbContext 注册为Transient,然后您尝试从LoadTestCleanUpServiceRepository 解析MyDbContext。那就是问题所在。根据ASP.NET Core Service lifetimes 文档:

从单例解析作用域服务/瞬态服务是很危险的。可能会导致服务在处理后续请求时状态不正确。

解决方法是:注册LoadTestCleanUpServiceRepository和MyDbContext如下:

services.AddDbContext<MyDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("YourConnectionStringName")));

services.AddScoped<ILoadTestCleanUpServiceRepository, LoadTestCleanUpServiceRepository>();

现在问题应该消失了。

【讨论】:

  • 谢谢。经过多次更改,它起作用了。真正错误的一件事是我定义了两个不同的数据库上下文(在尝试移动单个数据库上下文后发生意外)并且搞砸了。
猜你喜欢
  • 2021-05-09
  • 1970-01-01
  • 1970-01-01
  • 2019-09-30
  • 2021-05-31
  • 1970-01-01
  • 1970-01-01
  • 2012-02-23
  • 1970-01-01
相关资源
最近更新 更多