Использование DynamicProxy в качестве шаблона декоратора в контейнере Windsor - PullRequest
2 голосов
/ 17 февраля 2009

Я ищу информацию об использовании и настройке windsor для предоставления динамического прокси-сервера для перехвата вызовов экземпляра другого класса.

Мой класс представляет ресурс, который должен сохраняться контейнером в качестве долгоживущего экземпляра по соображениям производительности. Однако иногда этот ресурс может переходить в непригодное для использования состояние и требует обновления. Я хотел бы, чтобы контейнер обрабатывал это, чтобы клиентский код не должен был это делать. Я могу создать свою собственную фабрику, чтобы сделать это, я хотел бы знать, есть ли какая-то крутость регистрации в Виндзоре, чтобы сделать это для меня, поэтому мне не нужно создавать отдельный класс фабрики:)

Вот некоторый псевдокод, демонстрирующий проблему:

public interface IVeryImportantResource
{
    void SomeOperation();
}

public class RealResource : IVeryImportantResource
{
    public bool Corrupt { get; set; }

    public void SomeOperation()
    {
        //do some real implementation
    }
}

public class RealResourceInterceptor : IInterceptor
{
    private readonly IKernel kernel;

    public RealResourceInterceptor(IKernel Kernel)
    {
        kernel = Kernel;
    }

    public void Intercept(IInvocation invocation)
    {
        RealResource resource = invocation.InvocationTarget as RealResource;

        if(resource.Corrupt)
        {
            //tidy up this instance, as it is corrupt
            kernel.ReleaseComponent(resource);
            RealResource newResource = kernel.Resolve<RealResource>(); //get a new one
            //now what i would like to happen is something like this
            //but this property has no setter, so this doesn't work
            //also, i would like to know how to register RealResourceInterceptor as well RealResourceInterceptor
            invocation.InvocationTarget = newResource;
        }
        invocation.Proceed();
    }
}

Есть идеи, как реализовать что-то вроде моего класса RealResourceInterceptor, а также как настроить контейнер для его использования? Спасибо!

Ответы [ 2 ]

2 голосов
/ 17 февраля 2009

Этот вопрос больше касается обновления одноэлементного компонента, чем перехвата. На вопрос об обновлении синглетонов ответили на этот вопрос .

Итог: это не так просто, как кажется, с таким подходом есть много подводных камней.

Возможно, проблема заключается в повреждении этого компонента (почему это происходит?)

0 голосов
/ 17 февраля 2009

Мой объект - прокси WCF. Эти объекты перейдут в неисправное состояние, что делает их непригодными для использования. Я не могу контролировать, когда или если они будут переходить. Я могу только обнаружить, что это произошло, и воссоздать новый прокси.

Спасибо за ссылку, приведенный ниже раздел описывает примерно, как я сейчас это делаю:

В качестве альтернативы другой подход заключается в иметь декоратора к вашим услугам зарегистрирован в контейнере с единый образ жизни, но ваш актуальный базовый сервис зарегистрирован в контейнер с переходным образом жизни - тогда, когда вам нужно обновить компонент просто избавиться от переходный базовый компонент, удерживаемый декоратор и заменить его только что разрешенный экземпляр (разрешить его используя ключ компонентов, а не сервис, чтобы избежать получения декоратор) - это позволяет избежать проблем с другие одноэлементные сервисы (которые не являются будучи "освеженным") от удержания устаревшие услуги, которые были распорядился сделать их непригодными, но действительно нужно немного кастинга и т. д. заставить это работать

Мой вопрос, вместо одного из них:

1) использование статически типизированного декоратора, чтобы обернуть мой RealResource (как выше). Как только вы получаете несколько таких прокси-серверов, становится все труднее создавать декораторы для них всех.

2) использование объекта фабрики, который создает динамический прокси для управления состоянием любого прокси WCF.

2) намного выше, но кажется, что Виндзор уже может сделать для меня. Итак, я хотел бы знать, есть ли какой-нибудь контейнерный автомат, который позволит мне зарегистрировать перехватчик во время конфигурации вместо создания собственной фабрики?

Примерно так: псевдокод:

container.AddComponent("dynamicProxyWrapper", typeof(IRealResource), typeof(RealResource)).UsingInterceptor(typeof(RealResourceInterceptor));
...