Сообщение DispatchProxy от 05.09.2021 12:06
Изменено 05.09.2021 12:12 Разраб
DispatchProxy
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:
Вопрос в следующем: то, что при цепочном вызове методов интерфейса прокси перехватывает только первый это баг или фича?
Для меня это как минимум было неожиданно. Можно изменить поведение прокси?
DispatchProxy
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 расширение включил в код без особых надежд, хотя он как бы должен расширять интерфейс, но не является его частью.