使用Castle的动态代理时,我遇到了一些(我认为)奇怪的行为。
使用以下代码:
class Program
{
static void Main(string[] args)
{
var c = new InterceptedClass();
var i = new Interceptor();
var cp = new ProxyGenerator().CreateClassProxyWithTarget(c, i);
cp.Method1();
cp.Method2();
Console.ReadLine();
}
}
public class Interceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine(string.Format("Intercepted call to: " + invocation.Method.Name));
invocation.Proceed();
}
}
public class InterceptedClass
{
public virtual void Method1()
{
Console.WriteLine("Called Method 1");
Method2();
}
public virtual void Method2()
{
Console.WriteLine("Called Method 2");
}
}
我期待获得输出:
- 截获的电话:Method1
- 称为方法1
- 截获的电话:方法2
- 称为方法2
- 截获的电话:方法2
- 称为方法2
但我得到的是:
- 截获的电话:Method1
- 称为方法1
- 称为方法2
- 截获的电话:方法2
- 称为方法2
据我所知,如果调用来自类本身之外,动态代理只能代理方法调用,因为当从Program调用而不是从InterceptedClass调用时拦截了Method2。
我可以理解,当从代理类中进行调用时,它将不再通过代理,但只是想检查这是否是预期的,如果是,那么无论如何都要查看是否有所有调用被拦截而不管他们被叫到哪里?
谢谢
编辑:tl; dr - 我刚尝试以不同的方式创建代理,如下所述,它产生你所追求的输出。我只需要改变这个:
var c = new InterceptedClass();
var i = new Interceptor();
var cp = new ProxyGenerator().CreateClassProxyWithTarget(c, i);
对此:
var i = new Interceptor();
var cp = new ProxyGenerator().CreateClassProxy<InterceptedClass>(i);
据我了解,代理生成器有效地创建了一个包装器对象。它们是两个独立的对象 - 一个是围绕另一个的包装器,在包装层中有拦截等。
很难看出它是怎么回事 可以 改变了什么实例 InterceptedClass
做了自己的方法调用:
- DynamicProxy无法更改现有对象的类型;创建对象后,其类型是固定的
- DynamicProxy无法更改绑定现有对象的现有调用的方式
如果你想 Method1
打电话 Method2
通过 使用当前代理创建代码的包装器,您需要告诉包装器的现有对象,作为其中的字段或方法参数。
或者,可能有一种不同的方式来创建代理开始 - 代理的一个方法 是 在某种意义上说是目标对象。我怀疑你可能想看看 CreateClassProxy
而不是 CreateClassProxyWithTarget
- 我怀疑你是这样的事实 供应 导致你出问题的目标对象。
你所看到的行为是否“预期”或者显然取决于你的期望 - 但它肯定是什么 一世 期待,不知道任何关于城堡动态代理:)
编辑:tl; dr - 我刚尝试以不同的方式创建代理,如下所述,它产生你所追求的输出。我只需要改变这个:
var c = new InterceptedClass();
var i = new Interceptor();
var cp = new ProxyGenerator().CreateClassProxyWithTarget(c, i);
对此:
var i = new Interceptor();
var cp = new ProxyGenerator().CreateClassProxy<InterceptedClass>(i);
据我了解,代理生成器有效地创建了一个包装器对象。它们是两个独立的对象 - 一个是围绕另一个的包装器,在包装层中有拦截等。
很难看出它是怎么回事 可以 改变了什么实例 InterceptedClass
做了自己的方法调用:
- DynamicProxy无法更改现有对象的类型;创建对象后,其类型是固定的
- DynamicProxy无法更改绑定现有对象的现有调用的方式
如果你想 Method1
打电话 Method2
通过 使用当前代理创建代码的包装器,您需要告诉包装器的现有对象,作为其中的字段或方法参数。
或者,可能有一种不同的方式来创建代理开始 - 代理的一个方法 是 在某种意义上说是目标对象。我怀疑你可能想看看 CreateClassProxy
而不是 CreateClassProxyWithTarget
- 我怀疑你是这样的事实 供应 导致你出问题的目标对象。
你所看到的行为是否“预期”或者显然取决于你的期望 - 但它肯定是什么 一世 期待,不知道任何关于城堡动态代理:)