Мой случай это - Ninject 2.
// normal explicit dispose
using (var dc = new EFContext)
{
}
Но иногда я должен сохранить контекст дольше или между вызовами функции. Таким образом, я хочу управлять этим поведением через объем МОК.
// if i use this way. how do i make sure object is disposed.
var dc = ninject.Get<IContext>()
// i cannot use this since the scope can change to singleton. right ??
using (var dc = ninject.Get<IContext>())
{
}
Демонстрационные объемы
Container.Bind<IContext>().To<EFContext>().InSingletonScope();
// OR
Container.Bind<IContext>().To<EFContext>().InRequestScope();
Насколько я знаю (около месяца назад я проводил исследование), Ninject вообще не поддерживает управление жизненным циклом. Castle Windsor и AutoFac (и в некоторой степени StructureMap, но только при использовании вложенных контейнеров) позаботятся об утилизации одноразовых компонентов, которые они создают в надлежащее время.
Если у вас есть контроль над интерфейсом ] IContext
, добавьте IDisposable
в список интерфейсов, от которых он наследуется. Если нет, уменьшите IContext
до IDisposable ...
var context = ninject.Get<IContext>();
using ((IDisposable)context)
{
}
У вас также есть возможность изменить интерфейс IContext
, чтобы сделать это путем композиции, если вы управляете IContext
...
public interface IContext
{
// ...
IDisposable GetUsageHandle();
}
var context = ninject.Get<IContext>();
using (context.GetUsageHandle())
{
}
В дополнение к стандартным областям действия Transient, OnePerThread и Singleton, вы можете использовать ActivationBlock для управления временем жизни всего набора объектов. Когда блок удаляется, все объекты, полученные блоком, выходят за пределы области видимости, поэтому синглтоны и другие объекты удаляются, когда их экземпляры запрашиваются блоком активации.
var kernel = new StandardKernel();
kernel.Bind<NotifiesWhenDisposed>().ToSelf();
NotifiesWhenDisposed instance = null;
using(var block = new ActivationBlock(kernel))
{
instance = block.Get<NotifiesWhenDisposed>();
instance.IsDisposed.ShouldBeFalse();
}
instance.IsDisposed.ShouldBeTrue();