【问题标题】:How use IInterceptor in Castle.DynamicProxy?如何在 Castle.DynamicProxy 中使用 IInterceptor?
【发布时间】:2015-04-15 14:56:18
【问题描述】:

我写了一个这样的例子

简单计算器类:

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 类并继承自“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<Calculator>(new CalculatorInterceptor());
        var r = c.Add(11, 22);
        Console.WriteLine(r);
        Console.ReadKey();
    }

我没有看到这样的东西:

START
33
END

但只显示

33

我该如何纠正它?!

【问题讨论】:

    标签: c# interceptor castle-dynamicproxy dynamic-proxy interception


    【解决方案1】:

    另一种选择是制作一个 ICalculator 接口

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

    并从此接口继承您的类

    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 类中删除了 virtual,在我看来这是糟糕的设计,除非您将来有理由重写该方法。

    【讨论】:

      【解决方案2】:

      尝试使方法Add虚拟化。

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

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

      【讨论】:

      • 是的,似乎没问题,但结果是 START END 33 如何以正确的方式设置 Before & After 并查看类似 START 33 END 的结果,我可以在 Interceptor 类中更正此问题以获得正确的方法吗打电话??!!!
      • @user3153878 拦截器在Add 调用之前和之后执行,但是您将之后的结果写入控制台(执行之前-> 执行添加-> 执行之后-> 写入结果)。如果您在Add 方法中进行控制台调用,您应该会得到想要的结果。
      【解决方案3】:

      您必须使用正确的重载并传入您希望使用的目标对象和拦截器。方法应该是这样的:

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

      【讨论】:

        猜你喜欢
        • 2018-07-04
        • 1970-01-01
        • 2011-02-26
        • 1970-01-01
        • 2020-03-29
        • 1970-01-01
        • 2011-05-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多