Как мне управлять удалением объектов при использовании IoC? - PullRequest
5 голосов
/ 09 апреля 2010

В моем случае это Ninject 2.

// normal explicit dispose
using (var dc = new EFContext) 
{
}

Но иногда мне нужно держать контекст дольше или между вызовами функций. Поэтому я хочу контролировать это поведение через область действия IoC.

// 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();

Ответы [ 3 ]

3 голосов
/ 10 апреля 2010

Из того, что я знаю (я провел исследование около месяца назад), Ninject вообще не поддерживает управление жизненным циклом. Castle Windsor и AutoFac (и в некоторой степени StructureMap, но только при использовании вложенных контейнеров) позаботятся об утилизации одноразовых компонентов, которые они создают в соответствующее время.

1 голос
/ 03 июня 2010

В дополнение к стандартным областям действия 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();
1 голос
/ 09 апреля 2010

Если у вас есть контроль над интерфейсом 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())
{
}
...