在DependencyInjection之外创建DBContext

时间:2018-09-10 20:09:10

标签: c# entity-framework asp.net-core-2.0

我正在创建一个ASP.NET Core应用程序。它使用Entity Framework Core进行数据库访问。我在Startup.cs中使用services.AddDbContext,并且数据库上下文已按预期注入到我的控制器中。

我还有一个使用IHostedService的后台任务,该任务已添加为Singleton。我想在IHostedService的实现中有一个DBContext实例。尝试执行此操作时,出现运行时错误,提示我IHostedService无法使用作用域服务(数据库上下文)。

DB Context类采用DbContextOptions选项的参数,并将这些选项传递给基本构造函数(DbContext)。

我需要在IHostedService(单例对象)的实现中创建数据库上下文的实例,但似乎无法弄清楚如何从IHostedService的实现中正确创建DbContextOptions的新实例。

2 个答案:

答案 0 :(得分:2)

要从Scoped Service解析Singleton Service,可以从IServiceProvider创建作用域服务。

这是演示代码:

    public class DbHostedService : IHostedService
{
    private readonly ILogger _logger;

    public DbHostedService(IServiceProvider services,
        ILogger<DbHostedService> logger)
    {
        Services = services;
        _logger = logger;
    }

    public IServiceProvider Services { get; }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation(
            "Consume Scoped Service Hosted Service is starting.");

        DoWork();

        return Task.CompletedTask;
    }

    private void DoWork()
    {
        _logger.LogInformation(
            "Consume Scoped Service Hosted Service is working.");

        using (var scope = Services.CreateScope())
        {
            var context =
                scope.ServiceProvider
                    .GetRequiredService<ApplicationDbContext>();

            var user = context.Users.LastOrDefault();

            _logger.LogInformation(user?.UserName);
        }
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation(
            "Consume Scoped Service Hosted Service is stopping.");

        return Task.CompletedTask;
    }
}

参考:Consuming a scoped service in a background task

答案 1 :(得分:-1)

我认为您不需要IHostedService。迈比,您需要这个

public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<BlogContext>(options =>

       options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

        services.AddMvc();
        services.AddSession();
    }