Csharp/C#教程:为什么不会为* each * virtual方法调用调用DynamicProxy的拦截器?分享


为什么不会为* each * virtual方法调用调用DynamicProxy的拦截器?

一个例子最好地解释了:

public interface IA { void foo(); void bar(); } public class A : IA { public virtual void foo(){ Console.Write("foo"); bar(); //call virtual method } public virtual void bar(){ Console.Write("bar"); } } public class Interceptor : IInterceptor { public void Intercept(IInvocation invocation) { Console.WriteLine("Intercepted: " + invocation.Method.Name); invocation.Proceed(); } } Main(){ IA a = new A(); //proxy-ing an interface, given an implementation IA proxy = new Castle.DynamicProxy.ProxyGenerator() .CreateInterfaceProxyWithTarget(a, new Interceptor()); proxy.foo(); } 

我原本期望输出:

 Intercepted foo foo Intercepted bar bar 

相反,我得到:

 Intercepted foo foo bar 

为什么?

动态代理如何工作? 我期望生成的代理从代理类inheritance ,但是,似乎它使用组合将代理接口中的每个方法委托给实际的实现。

我尝试使用Castle DynamicProxy以及Cramon的旧动态代理实现

看起来我的猜测是正确的。

我尝试了同样的例子,这次只是直接从类类型创建代理:

 Main(){ //proxy-ing an explicit type A proxy = (A) new Castle.DynamicProxy.ProxyGenerator() .CreateClassProxy(new Interceptor()); proxy.foo(); } 

结果是我首先想到的:

 Intercepted foo foo Intercepted bar bar 

这导致我得出以下结论:

使用接口实现创建接口代理时,生成的代理看起来像这样:

 class InterfaceProxy: IA { //implements interface IA m_impl; [...] Proxy(IA i_impl){ m_impl = i_impl; } public void foo(){ //overly-simplified, but you get the picture InvokeInterceptors("foo"); //execution gets here when calling 'invocation.Proceed()' //from the interceptor m_impl.foo(); //pass the execution to the implementation; //the proxy has no more control over what gets executed. } public void bar(){ InvokeInterceptors("bar"); m_impl.bar(); } } 

创建类代理时,代码如下所示:

 class ClassProxy: A { //inherits class type Proxy(): base() { ... } public override void foo(){ InvokeInterceptors("foo"); //execution gets here when calling 'invocation.Proceed()' //from the interceptor base.foo(); //pass the execution to the base class } public void bar(){ InvokeInterceptors("bar"); base.bar(); } } 

您正在使用CreateInterfaceProxyWithTarget方法,该方法指示代理构建器为接口创建代理并将调用转发给目标对象,因此您所看到的就是您要求它执行的操作。

如果您希望代理从您的类派生,那么您需要使用CreateClassProxy方法。

上述就是C#学习教程:为什么不会为* each * virtual方法调用调用DynamicProxy的拦截器?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/987833.html

(0)
上一篇 2021年12月23日
下一篇 2021年12月23日

精彩推荐