Accessing DbContext after it is disposed will cause a “Cannot access a disposed object in dotnet Core when injecting DbContext” error.
Entity Framework (EF) Core is a lightweight, open-source. EF Core can serve as an object-relational mapper (O/RM). A DbContext instance represents a session with the database and can be used to query and save instances of your entities.
DbContext is a combination of the Unit Of Work and Repository patterns and it is not thread-safe.
DbContext should not be accessed by multiple threads at the same time. In the dot net core, there are different possibilities of getting this error.
Possibility of getting Cannot access a disposed object error
When DbContext is used by multiple threads, one thread opens the connection to execute the query, and meanwhile, the second thread might have executed its query and closes the connection.
When this happens, the first thread throws an error that the DbContext is disposed. Avoid using multithreading with DbContext. Read more on working with DbContext
In dot net core, we have three service lifetime. Most of the time, DbContext is configured to be scoped service.
- Transient
- Scoped
- Singleton
When an http request is served and returned with response, if you access DbContext service instance in any of the background work, then you will get this error.
Refer to this post for more details on how to Implement background tasks using IHostedService and access scoped service using IServiceScopeFactory
How to access scoped service using IServiceScopeFactory
Inject IServiceScopeFactory in the constructor and using this service you can get scoped service as described below.
private readonly ILogger<StatusCheckerService> logger; private readonly IServiceScopeFactory serviceScopeFactory; public StatusCheckerService( ILogger<StatusCheckerService> logger,IServiceScopeFactory serviceScopeFactory) { this.logger = logger; this.serviceScopeFactory = serviceScopeFactory; } //In the method where you need scoped service, use below. using (var scope = serviceScopeFactory.CreateScope()) { // You can ask for any service here and DI will resolve it and give you back service instance var contextService = scope.ServiceProvider.GetRequiredService<IContextService&ht;(); contextService.YourMethodOrServiceMethod(); //access dbcontext or anything thats available form your service }
Related Posts
- Implement create, read, update, and delete functionalities using Entity Framework Core
- Working with optional body parameters in ASP.NET Core 2.2
- How to upload a file with .NET CORE Web API 3.1 using IFormFile
Conclusion
In this post, I showed how to avoid Cannot access a disposed object in dotnet Core when injecting DbContext error. That’s all from this post. If you have any questions or just want to chat with me, feel free to leave a comment below