Ninject - In what scope DbContext should get binded when RequestScope is meaningless?
dependency-injection, entity-framework, multithreading, ninject, threadpool
Solution
If you decide to go on with custom scope, the solution is:
public sealed class CurrentScope : INotifyWhenDisposed
{
[ThreadStatic]
private static CurrentScope currentScope;
private CurrentScope()
{
}
public static CurrentScope Instance => currentScope ?? (currentScope = new CurrentScope());
public bool IsDisposed { get; private set; }
public event EventHandler Disposed;
public void Dispose()
{
this.IsDisposed = true;
currentScope = null;
if (this.Disposed != null)
{
this.Disposed(this, EventArgs.Empty);
}
}
}
Binding:
Bind<DbContext>().To<MyDbContext>().InScope(c => CurrentScope.Instance)
And finally:
using (CurrentScope.Instance)
{
// your request...
// you'll get always the same DbContext inside of this using block
// DbContext will be disposed after going out of scope of this using block
}
Problem
In an MVC / WebAPI environment I would use `InRequestScope` to bind the `DbContext`. However, I am now on a Console application / Windows service / Azure worker role (doesn't really matter, just there's no Web request scope), which periodically creates a number of `Tasks` that run asynchronously. I would like each task to have its own `DbContext`, and since tasks run on their own thread, I tried binding `DbContext` using `InThreadScope`. Unfortunately, I realize that the DbContext is not disposed when a task is finished. What actually happens is, the thread returns to the Thread Pool and when it is assigned a new task, it already has a DbContext, so DbContexts stay alive forever. Is there a way `InThreadScope` can be used here or should I use some other scope? How can ThreadScope be used when threads are returning from ThreadPool every now and then?