DispatchProxy
От: vaa  
Дата: 05.09.21 12:06
Оценка:
    public interface IDoer
    {
        IDoer Hello();
        IDoer GoodBye();
    }
    public static class DoerExtensions
    {
        public static IDoer Welcome(this IDoer it)
        {
            WriteLine("Welcome");
            return it;
        }
    }
    public class Doer : IDoer
    {
        public IDoer Hello()
        {
            WriteLine("Hello");
            return this;
        }

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

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

вывод:

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


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

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


PS расширение включил в код без особых надежд, хотя он как бы должен расширять интерфейс, но не является его частью.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Отредактировано 05.09.2021 12:12 Разраб . Предыдущая версия . Еще …
Отредактировано 05.09.2021 12:06 Разраб . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.