我在处理数据库上下文时遇到问题。我已经在“配置服务”方法中设置了以下数据库。该代码已简化,希望可以使其更易于阅读。
public void ConfigureServices(IServicesCollection services)
{
Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("Database1")));
Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("Database2")));
Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("Database3")));
Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("Database4")));
Services.AddScoped<IQueryService1, ConcreteService1>();
Services.AddScoped<IQueryService1, ConcreteService2>();
Services.AddScoped<IQueryService1, ConcreteService3>();
Services.AddScoped<IQueryService1, ConcreteService4>();
}
现在,在其中一个控制器中,我注入了所需的相关服务。
[Produces("application/json")]
[Route("api/[controller]/[action]
public class DigitalFinesController : Controller
{
private readonly IQueryService1 _Service1;
public DigitalFinesController(IConfiguration configuration, IQueryServices1 QueryService1)
{
_Service1 = QueryService1;
}
[Authorize]
[HttpPost]
[ActionName("SubmitFine")]
[ProducesResponseType(200)]
[ProducesResponseType(401)]
public async Task<IActionResult> SubmitFine([FromBody] Models.DigitalFine fine)
{
//This is a simple version of my issue
var vehicles = _Service1.Vehicles.FirstOrDefault(p=> p.vrm == "OX7 DFG");
if(vehicle == null)
{
return BadRequest("Vehicle is missing");
}
var fleet = _Service1.Fleets.FirstOrDefault(p=> p.Code = "MyCode");
}
}
一旦我进入第二个查询,我就会得到以下异常
System.ObjectDisposedException:'无法访问已处置的对象。导致此错误的常见原因是,处理从依赖项注入中解决的上下文,然后稍后尝试在应用程序中的其他位置使用相同的上下文实例。如果在上下文上调用Dispose()或将上下文包装在using语句中,则可能会发生这种情况。如果您正在使用依赖项注入,则应让依赖项注入容器来处理上下文实例。
我很困惑,为什么会这样。谁能给我指点一下解决这个问题?
非常感谢 西蒙
答案 0 :(得分:2)
我认为这可能与您的注册方式有关。尝试使用AddSingleton
而不是AddScoped
作用域
范围内的生命周期服务每个请求创建一次。
警告
在中间件中使用作用域服务时,请将服务注入Invoke或InvokeAsync
方法中。不要通过构造函数注入进行注入,因为它会强制服务表现为单例。有关更多信息,请参见ASP.NET Core中间件。
单人
单生命周期服务是在首次请求它们时创建的(或者在运行ConfigureServices
并使用服务注册指定实例时创建)。每个后续请求都使用相同的实例。如果应用程序要求单例行为,则建议允许服务容器管理服务的生命周期。不要实现单例设计模式,不要在类中提供用户代码来管理对象的生存期。
警告
从单例中解析作用域服务很危险。处理后续请求时,可能导致服务的状态不正确。
答案 1 :(得分:2)
.AddScoped
将在对象的第一次数据库调用之后处理:
请参阅文档: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.2
在此部分:
在示例应用程序中,IMyDependency服务已向 具体类型为MyDependency。注册范围服务 生存期到单个请求的生存期。服务寿命是 在本主题的后面进行介绍。