Cri*_*scu 11 c# castle-dynamicproxy proxy-classes dynamic-proxy
一个例子最好地解释了:
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();
}
Run Code Online (Sandbox Code Playgroud)
我原本期望输出:
Intercepted foo
foo
Intercepted bar
bar
Run Code Online (Sandbox Code Playgroud)
相反,我得到:
Intercepted foo
foo
bar
Run Code Online (Sandbox Code Playgroud)
为什么?
动态代理如何工作?我期望生成的代理从代理类继承,但是,似乎它使用组合将代理接口中的每个方法委托给实际的实现.
我尝试使用Castle DynamicProxy以及Cramon的旧动态代理实现
Cri*_*scu 14
看起来我的猜测是正确的.
我尝试了同样的例子,这次只是直接从类类型创建代理:
Main(){
//proxy-ing an explicit type
A proxy = (A) new Castle.DynamicProxy.ProxyGenerator()
.CreateClassProxy<A>(new Interceptor());
proxy.foo();
}
Run Code Online (Sandbox Code Playgroud)
结果是我首先想到的:
Intercepted foo
foo
Intercepted bar
bar
Run Code Online (Sandbox Code Playgroud)
这导致我得出以下结论:
使用接口实现创建接口代理时,生成的代理看起来像这样:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
创建类代理时,代码如下所示:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
您正在使用CreateInterfaceProxyWithTarget指示代理构建器为接口创建代理并将调用转发到目标对象的方法,因此您所看到的就是您要求它执行的操作.
如果您希望代理从您的类派生,那么您需要使用该CreateClassProxy方法.