Я использую фреймворк Castle-Windsor и хочу вызвать фрагмент кода непосредственно перед тем, как фреймворк выпустит конкретный (сторонний) компонент.
Я подумал, что мог бы сделать это, добавивделегат OnDestroy
, но фреймворк всегда сначала вызывает Dispose
.(См. Пример ниже).
Какие варианты у меня есть для вызова кода до вызова Dispose
?
public class TestClass : IDisposable
{
static long _globalInstanceCount = 0;
readonly long _instanceId;
public TestClass()
{
_instanceId = Interlocked.Increment(ref _globalInstanceCount);
Trace.WriteLine(string.Format("TestClass ({0}) - Constructor called", _instanceId));
}
public void ByeBye()
{
Trace.WriteLine(string.Format("TestClass ({0}) - ByeBye called", _instanceId));
}
void IDisposable.Dispose()
{
Trace.WriteLine(string.Format("TestClass ({0}) - Dispose called", _instanceId));
}
}
class Program
{
static void Main(string[] args)
{
{
Trace.WriteLine("Testing as a singleton");
var container = new WindsorContainer()
.Register(Component.For<TestClass>()
.LifeStyle.Singleton
.OnDestroy(t => t.ByeBye())
);
TestClass tc = container.Resolve<TestClass>();
Trace.WriteLine("Releasing the component");
container.Release(tc);
Trace.WriteLine("Disposing of the container");
container.Dispose();
}
{
Trace.WriteLine("Testing transient");
var container = new WindsorContainer()
.Register(Component.For<TestClass>()
.LifeStyle.Transient
.OnDestroy(t => t.ByeBye())
);
TestClass tc = container.Resolve<TestClass>();
Trace.WriteLine("Releasing the component");
container.Release(tc);
Trace.WriteLine("Disposing of the container");
container.Dispose();
}
}
}
Это приводит к следующему выводу.Как видите, ByeBye
вызывается после Dispose
.
Тестирование как одиночного
TestClass (1) - Конструктор называется
Выпуск компонента
Утилизация контейнера
TestClass (1) - Утилизация называется
TestClass (1) - ByeBye называется
Тестирование переходного процесса
TestClass (2) - конструктор с именем
освобождение компонента
TestClass (2) - удаление с именем
TestClass (2) - ByeBye с вызовом
удаление изконтейнер
Я пытался решить эту проблему с помощью перехватчика, но оказывается, что фреймворк Windsor вызывает Dispose
для исходного компонента , минуя любые перехватчики .
Trace.WriteLine("Testing transient with interceptor");
var container = new WindsorContainer()
.Register(Component.For<TestClassInterceptor>().LifeStyle.Transient,
Component.For<TestClass>()
.LifeStyle.Transient
.OnDestroy(t => t.ByeBye())
.Interceptors<TestClassInterceptor>()
);
TestClass tc = container.Resolve<TestClass>();
tc.Hello();
Trace.WriteLine("Releasing the component");
container.Release(tc);
Trace.WriteLine("Disposing of the container");
container.Dispose();
Результатом будет следующий вывод.Смотрите, что TestClass (3) - Dispose
вызывается независимо от перехватчика.
Тестирование переходного процесса с перехватчиком
TestClassInterceptor (1) - Конструктор называется
TestClass (3) - Конструкторзвонил
TestClassInterceptor (1) - Метод Перехвата "Hello"
TestClass (3) - Здравствуйте звонил
Выпуск компонента
TestClass (3) -Уничтожить вызываемый
TestClassInterceptor (1) - Метод перехвата "ByeBye"
TestClass (3) - ByeBye вызвал
TestClassInterceptor (1) - Уничтожить вызываемый
Утилизация контейнера