【问题标题】:Getting DbContext when resolving a singleton解析单例时获取 DbContext
【发布时间】:2017-09-20 16:32:00
【问题描述】:

ConfigureServices我有

services.AddDbContext<MyContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

还有

services.AddSingleton<IMyModel>(s =>
{
    var dbContext = s.GetService<MyContext>();
    var lastItem= dbContext.Items.LastOrDefault();
    return new MyModel(lastItem);
});

但是s.GetService&lt;MyContext&gt;() 抛出错误:

无法从根提供程序解析范围服务“MyContext”。

我怎样才能做到这一点?我不想在MyModel 构造函数中注入MyDbContext,因为它在一个没有理由知道Entity Framework 的库中。

【问题讨论】:

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


    【解决方案1】:

    AddDbContext 默认使用scoped 生活方式:

    范围内的生命周期服务 (AddScoped) 为每个客户端请求(连接)创建一次。

    引发错误的原因是您试图从请求外部获取MyContext 的实例。正如错误消息所示,无法从根 IServiceProvider 获取 scoped 服务。

    出于您的目的,您可以显式创建一个范围并将其用于您的依赖关系解析,如下所示:

    services.AddSingleton<IMyModel>(sp =>
    {
        using (var scope = sp.CreateScope())
        {
            var dbContext = scope.ServiceProvider.GetService<MyContext>();
            var lastItem = dbContext.Items.LastOrDefault();
            return new MyModel(lastItem);
        }
    });    
    

    上面的代码创建了一个scoped IServiceProvider,可用于获取scoped服务。

    【讨论】:

    • 服务器启动时new MyModel(lastItem)的行只会被调用一次对吗?所以 lastItem 在服务器启动时从数据库中加载,并且在服务器运行时将新项目添加到数据库中时永远不会改变
    • @SimonHeinen 是的,没错。 技术上,它会在第一次请求IMyModel 时发生,但它只是一次并且不会改变,正如你所说的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-12
    • 1970-01-01
    • 1970-01-01
    • 2020-08-27
    • 1970-01-01
    相关资源
    最近更新 更多