如何在Castle.DynamicProxy中使用IInterceptor?

我写了一个这样的例子

简单计算器类:

public class Calculator { public int Add(int a, int b) { return a + b; } } 

实现了DynamicProxy提供的“IInterceptor”

  [Serializable] public abstract class Interceptor : IInterceptor { public void Intercept(IInvocation invocation) { ExecuteBefore(invocation); invocation.Proceed(); ExecuteAfter(invocation); } protected abstract void ExecuteAfter(IInvocation invocation); protected abstract void ExecuteBefore(IInvocation invocation); } 

创建了一个Interceptor类,并inheritance自“Interceptor”类

  public class CalculatorInterceptor : Interceptor { protected override void ExecuteBefore(Castle.DynamicProxy.IInvocation invocation) { Console.WriteLine("Start"); } protected override void ExecuteAfter(Castle.DynamicProxy.IInvocation invocation) { Console.WriteLine("End"); } } 

但是当我用它时不工作!

 static void Main(string[] args) { ProxyGenerator generator = new ProxyGenerator(); Calculator c = generator.CreateClassProxy(new CalculatorInterceptor()); var r = c.Add(11, 22); Console.WriteLine(r); Console.ReadKey(); } 

我除外看到这样的事情:

 START 33 END 

但只显示

 33 

我怎么纠正它?!

尝试制作Add虚拟方法。

 public class Calculator { public virtual int Add(int a, int b) { return a + b; } } 

代理生成器创建一个inheritanceCalculator的新类。 因此,方法Add获取覆盖以使拦截成为可能。

另一种选择是建立ICalculator接口

 public interface ICalculator { int Add(int a, int b); } 

并从此接口inheritance您的类

 public class Calculator : ICalculator { public int Add(int a, int b) { return a + b; } } 

然后,您的动态代理将使用CreateInterfaceProxyWithTarget方法

 var proxyGenerator = new ProxyGenerator(); ICalculator calculator = new Calculator() var proxy = proxyGenerator.CreateInterfaceProxyWithTarget( calculator, ProxyGenerationOptions.Default, new CalculatorInterceptor()); Console.WriteLine(proxy.Add(1, 2)); 

这会从你的Calculator类中删除虚拟,在我看来这是不好的设计,除非你有理由在将来覆盖该方法。

您必须使用正确的重载并传入目标对象和您想要使用的拦截器。 方法应如下所示:

 var proxy = generator.CreateClassProxy(new Calculator(), new CalculatorInterceptor() );