Re: DispatchProxy
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 05.09.21 13:27
Оценка: 8 (1)
Здравствуйте, vaa, Вы писали:


vaa>
vaa>    public interface IDoer
vaa>    {
vaa>        IDoer Hello();
vaa>        IDoer GoodBye();
vaa>    }
vaa>    public static class DoerExtensions
vaa>    {
vaa>        public static IDoer Welcome(this IDoer it)
vaa>        {
vaa>            WriteLine("Welcome");
vaa>            return it;
vaa>        }
vaa>    }
vaa>    public class Doer : IDoer
vaa>    {
vaa>        public IDoer Hello()
vaa>        {
vaa>            WriteLine("Hello");
vaa>            return this;
vaa>        }

vaa>        public IDoer GoodBye()
vaa>        {
vaa>            WriteLine("Goodbye");
vaa>            return this;
vaa>        }
vaa>    }

vaa>    public class DoerProxy : DispatchProxy
vaa>    {
vaa>        public IDoer Target { get; private set; }
vaa>        public static IDoer Decorate(IDoer target = null)
vaa>        {
vaa>            var proxy = Create<IDoer, DoerProxy>() as DoerProxy;
vaa>            proxy.Target = target ?? Activator.CreateInstance<Doer>();
vaa>            return proxy as IDoer;
vaa>        }
vaa>        protected override object Invoke(MethodInfo targetMethod, object[] args)
vaa>        {
vaa>            Write("Proxy call: ");
vaa>            return targetMethod.Invoke(Target, args);
vaa>        }
vaa>    }
vaa>...........................
vaa> IDoer doer = new Doer();
vaa>            WriteLine("core proxy:");
vaa>            IDoer doerCore = DoerProxy.Decorate(doer);
vaa>            _ = doerCore.Hello().GoodBye().Welcome(); // <= 
vaa>            _ = doerCore.Hello();
vaa>            _ = doerCore.Welcome(); 
vaa>            _ = doerCore.GoodBye();
vaa>

vaa>вывод:
vaa>

vaa>Proxy call: Hello
vaa>Goodbye
vaa>Welcome
vaa>Proxy call: Hello
vaa>Welcome
vaa>Proxy call: Goodbye
vaa>Castle proxy:


vaa>Вопрос в следующем: то, что при цепочном вызове методов интерфейса прокси перехватывает только первый это баг или фича?

vaa>Для меня это как минимум было неприятной неожиданностью. Можно изменить поведение прокси?

vaa>Быть может с помощью Castle.DynamicProxy?

vaa>Вот такой код не справился с задачей(аналогично коровской реализации).
vaa>
vaa>public class DoerCastleProxy : IInterceptor
vaa>    {
vaa>        public void Intercept(IInvocation invocation)
vaa>        {
vaa>            Write("Castle call: ");
vaa>            invocation.Proceed();
vaa>        }
vaa>    }
vaa>......
vaa> ProxyGenerator generator = new ProxyGenerator();
vaa>            IDoer doerCastle = generator.CreateInterfaceProxyWithTargetInterface<IDoer>(doer, new DoerCastleProxy());
vaa>            _ = doerCastle.Hello().GoodBye().Welcome();
vaa>


vaa>PS расширение включил в код без особых надежд, хотя он как бы должен расширять интерфейс, но не является его частью.


Ну по уму ты должен сделать оберту и в

protected override object Invoke(MethodInfo targetMethod, object[] args)
       {
            Write("Proxy call: ");
            var result = targetMethod.Invoke(Target, args);
if (result is IDoer d)
{
var proxy = Create<IDoer, DoerProxy>() as DoerProxy;
    proxy.Target = d;
return proxy;
}
return result;
}
        }
и солнце б утром не вставало, когда бы не было меня
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.