Regardless of the comments questioning design quality, valid scenarios exist were the dbContext could be in a disposed state, such as (not a complete list):
For example (within injected dbContext MVC services):
- your service iterates though a lower tier of one-or-more service calls, possibly using asynchronous socket handler on a lower tier API library, with each response using the parent requester dbContext.
- Your service calls a database job, (asynchronous task or not).
- Exception handling logging to database (if the dbContext is already lost - avoid loss of logging debug details)
Note: Long running processes using dbContext like this should follow good practice of avoiding dbContext bloat such as using AsNoTracking() method were possible - as bloat can quickly become a concern.
Performance consideration:
Most trusted option is to recreate the dbContext on each child (api call/async task), but this may incur undesired performance overheads, such as when dealing with 1000's of api iterative calls and atomic unit transactions are not viable.
Solution Tested Using Framework:
Entity Type: Microsoft.EntityFrameworkCore.DbContext
Version=5.0.16.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
Warnings:
Lots of warning advice available on this type of extended dbContext use, such use should be used with caution/avoided where possible.
See warning details : c-sharp-working-with-entity-framework-in-a-multi-threaded-server
Extend you DbContext with partial class Or add method to your existing extended partial class.
FYI - Please comment if still working on updated EntityFrameworkCore libraries.
public partial class FooDbContext : DbContext
{
// Using Type: 5.0.16.0 EntityFrameworkCore.DbContext (confirm if working with any core library upgrades)
public bool IsDisposed()
{
bool result = true;
var typeDbContext = typeof(DbContext);
var isDisposedTypeField = typeDbContext.GetField("_disposed", BindingFlags.NonPublic | BindingFlags.Instance);
if (isDisposedTypeField != null)
{
result = (bool)isDisposedTypeField.GetValue(this);
}
return result;
}
}
Usage:
if (fooDbContext == null || fooDbContext.IsDisposed())
{
// Recreate context
}