首页 > 解决方案 > 为什么是 services.AddDbContext() 使 dbContext 成为 Scoped 服务?不应该是 Singleton 服务吗?

问题描述

我正在使用带有 Pomelo.EntityFramework.MySql 的 ASP.NET Core 2.2。

这是我的代码:

 services.AddDbContext<dbContext>(options => options.UseMySQL(appConfigsSection["DbConnectionString"]));
 services.AddSingleton<IUserService, UserService>();


 services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(x=> {
                x.Events = new JwtBearerEvents
                {
                    OnTokenValidated = context =>
                    {
                        var userService = context.HttpContext.RequestServices.GetRequiredService<IUserService>();       
                    }
                };

这是错误:

asp.net core 无法使用单例的范围服务

线上:

 var userService = context.HttpContext.RequestServices.GetRequiredService<IUserService>(); 

我的理解是 DBContext 应该用作 Singleton 服务,IUserService 也是如此。但似乎 DBContext 被视为 Scoped Service。

我可以通过将 IUserService 切换回 Scoped Service 轻松修复它。但我想知道为什么我不能将 DBContext 用作单一服务?

我认为 DBContext 应该用作 Singleton 服务,对吗?

这里

标签: c#entity-frameworkasp.net-coreentity-framework-core

解决方案


DbContext 不应该用作单例,因为它持有一个不能被多个线程同时使用的连接对象。如果两个请求同时尝试使用它,您将遇到错误。如果您的服务依赖于上下文,则该服务不能是单例。

Scoped 是有意义的,因为它允许您在服务之间传递 DB 对象并在所有服务中获取相同的 DbContext,因此您可以在一个服务中查询实体并将更改保存在另一个服务中。

例如,如果您需要在两个服务中并行运行查询,您可以将其更改为瞬态。服务生命周期是 AddDbContext() 上的一个参数。


推荐阅读