Как я могу заставить часть кода выполняться до удаления компонента? - PullRequest
3 голосов
/ 17 января 2012

Я использую фреймворк 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) - Уничтожить вызываемый

Утилизация контейнера

...