使用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");
}
}
我期待获得输出:
但我得到的是:
据我所知,如果调用来自类本身之外,动态代理只能代理方法调用,因为当从Program调用而不是从InterceptedClass调用时拦截了Method2。
我可以理解,当从代理类中进行调用时,它将不再通过代理,但只是想检查这是否是预期的,如果是,那么看看是否有任何方式来获取所有调用无论他们从哪里被拦截都被拦截了?
谢谢
答案 0 :(得分:16)
编辑: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
的实例用自己的方法调用所做的事情:
如果您希望Method1
使用当前代理创建代码通过通过包装器调用Method2
,您需要告诉现有对象有关包装器的信息,或者其中的字段或方法参数。
或者,可能有一种不同的方式来创建代理开始 - 代理 在某种意义上是目标对象。我怀疑你可能想看CreateClassProxy
而不是CreateClassProxyWithTarget
- 我怀疑你是提供导致你出现问题的目标对象。
您所看到的行为是否“预期”或不显着取决于您的期望 - 但它肯定是我期望的,而不知道有关Castle Dynamic Proxy的任何信息:)