c# - 为什么是 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 服务,对吗?
解决方案
DbContext 不应该用作单例,因为它持有一个不能被多个线程同时使用的连接对象。如果两个请求同时尝试使用它,您将遇到错误。如果您的服务依赖于上下文,则该服务不能是单例。
Scoped 是有意义的,因为它允许您在服务之间传递 DB 对象并在所有服务中获取相同的 DbContext,因此您可以在一个服务中查询实体并将更改保存在另一个服务中。
例如,如果您需要在两个服务中并行运行查询,您可以将其更改为瞬态。服务生命周期是 AddDbContext() 上的一个参数。
推荐阅读
- laravel - 在 Laravel Query Builder 子查询函数中访问列值作为变量
- flutter - sqflite IN 运算符与 AND 运算符
- css - Ionic 4:如何覆盖不受 css 变量控制的阴影元素中的样式?
- snowflake-cloud-data-platform - 我们如何在 Snowflake 中使用子查询,从 (select....) 中选择列失败
- stm32 - STM32F4 - 丢失来自 max30100 的 FIFO 数据样本
- c# - 取消 Abot 上的站点抓取
- machine-learning - 值错误:训练折叠中只有 2 个类/es,但整个数据集中有 1 个。具有不平衡折叠的决策函数不支持此功能
- c# - 如何绑定数据库中的图像并在gridview中显示图像?
- batch-file - 有没有办法获取使用 taskkill /f /fi “status eq notresponsive”杀死的进程的名称?
- sql - 获取连接中的最后一个条目