Использование Castle Dynamic Proxy - возможно контролировать и / или удалять перехватчики - PullRequest
1 голос
/ 07 июля 2011

Я сделал простое тестирование библиотеки Castle Dynamic Proxy:

public class Printer
{
    public virtual void Write(string msg)
    {
        Console.Write(msg); 
    }
}

public class CastleDynamicProxy
{
    public static void Test()
    {
        ProxyGenerator generator = new ProxyGenerator();

        Printer logger = generator.CreateClassProxy<Printer>(new TestInterceptor());

        logger.Write("Hello, World!"); 
    }
}

Теперь в моем перехватчике я хочу определить время функции, но она вызывает StackOverflowException, потому что я вызываю целевой метод внутри метода Intercept, вызывая бесконечный цикл:

public class TestInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
       var accessor = invocation.Proxy as IProxyTargetAccessor;

       MethodInfo target = accessor.DynProxyGetTarget().GetType().GetMethod("Write"); 

       var s = Stopwatch.StartNew(); 

       target.Invoke(invocation.InvocationTarget, invocation.Arguments);

       s.Stop(); 
    }
}

Есть ли что-нибудь вокруг этого: либо 1) полностью остановить процесс перехвата, либо 2) удалить мой перехватчик после того, как я использовал его для того, что мне нужно, перед тем как попасть в бесконечный цикл?

1 Ответ

3 голосов
/ 07 июля 2011

Вы уверены, что это то, что вы хотите сделать?Я также создал перехватчик времени, чтобы увидеть, превышает ли порог метода (например, запрос к БД) порог, и если это так, регистрировать его.

Вместо того, чтобы вручную вызывать цель, просто используйте invocation.Proceed(), чтобы сказать ей, чтобы она продолжала перехватывать вызов.

Мой код выглядит так:

        public void Intercept(IInvocation invocation)
        {
            var timer = Stopwatch.StartNew();

            // i think you want this to proceed with the invocation...
            invocation.Proceed();

            timer.Stop();

            // check if threshold is exceeded
            if (timer.Elapsed > _threshold)
            {
                // log it to logger of choice
            }
        }
...