为什么不会为* each * virtual方法调用调用DynamicProxy的拦截器? [英] Why won't DynamicProxy's interceptor get called for *each* virtual method call?

查看:132
本文介绍了为什么不会为* each * virtual方法调用调用DynamicProxy的拦截器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个例子最好地解释了:

An example explains it best :

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

为什么?

动态代理如何工作?
我希望生成的代理能够从代理类继承继承,但似乎它使用组合将代理接口中的每个方法委托给实际的实施。

How does the dynamic proxy work? I was expecting the generated proxy to inherit from the proxied class, however, it seems that it uses composition to delegate each of the methods in the proxied interface to the actual implementation.

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

I've tried with Castle DynamicProxy and also with an older dynamic proxy implementation, from Cramon

推荐答案

看起来我猜对了。

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

I tried the same example, only this time creating the proxy directly from the class type:

Main(){

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

}

结果是我的预期:

Intercepted foo
foo
Intercepted bar
bar

这导致我得出以下结论:

This leads me to the following conclusion:


  • 从接口创建代理时,它使用组合将调用委托给实现

  • 从(类)类型创建代理时,从类型继承,因此类类型中的所有虚拟调用都将调用代理中的重写方法。

  • when creating a proxy from an interface, it uses composition to delegate calls to the implementation
  • when creating a proxy from a (class) type, it inherits from the type, so all virtual calls in the class type will call the overridden methods in the proxy.

使用接口实现创建接口代理,生成的代理如下所示:

When creating an interface proxy with an interface implementation, the generated proxy looks something like this:

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();
  }
}

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

When creating a class proxy, the code looks like this:

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();
  }
}

这篇关于为什么不会为* each * virtual方法调用调用DynamicProxy的拦截器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆