I have a windows service which periodically runs some jobs using NCron. I recently introduced Ninject and got some serious memory issues due to the fact that the EF context (ObjectContext from EF4.1) is not GC'ed (I memory-profiled it).
It might be worth mentioning that some of these jobs are quite long running (10-15min) and are database intensive. I know EF is probably not the best solution for this kind of work but this it's impossible to refactor at this point.
I found quite a bit of material on this subject so I went ahead with:
- Implementing INotifyWhenDisposed in my job classes
- Trying to define EF context binding in a named scope, hoping it'll get disposed and GC'ed properly when the job is finished
I cannot seem to get the 2nd one to work, I get an ActivationException that the named scope does not exist.
Here's a simple piece of code I tried in debug mode that replicates this:
const string Scope = "Scope";
kernel.Bind(c => c.FromThisAssembly()
.SelectAllClasses().InheritedFrom<MyCronJob>()
.BindToSelf()
.Configure(b => b.DefinesNamedScope(Scope)));
kernel.Bind<IMyContext>().To<MyContext>().InNamedScope(Scope);
kernel.Get<ProcessImportJob>().DoWork();
And then
internal class ProcessImportJob : MyCronJob
{
private readonly IMyContext _ctx;
public ProcessImportJob(IMyContext ctx)
I cut the rest for brevity.
What am I doing wrong?
UPDATE 1 - Constructor injection works, it's when I do an explicit .Get<T>
that the exception occurs.