为什么services.AddDbContext <dbcontext>()使dbContext成为范围服务?应该不是Singleton服务?

时间:2019-04-17 07:25:17

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

我正在将ASP.NET Core 2.2与Pomelo.EntityFramework.MySql一起使用。

这是我的代码:

 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核心无法使用单例的作用域服务

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

我的理解是DBContext应该用作Singleton服务,IUserService也应该用作。 但是似乎DBContext被视为范围服务。

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

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

here

1 个答案:

答案 0 :(得分:5)

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

作用域是有道理的,因为它允许您在服务之间传递数据库对象并在所有服务中获得相同的DbContext,以便您可以查询一个服务中的实体并将更改保存到另一个服务中。

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