web-dev-qa-db-ja.com

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クラスを作成し、「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

どうすれば修正できますか?!

17
user3153878

メソッドをAdd仮想にしてみてください。

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

プロキシジェネレータは、Calculatorを継承する新しいクラスを作成します。したがって、メソッドAddは、傍受を可能にするオーバーライドを取得します。

17
Axel Heer

他のオプションは、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クラスから仮想が削除されます。これは、将来メソッドをオーバーライドする理由がない限り、悪い設計だと思います。

6
Jeff Vanzella

正しいオーバーロードを使用して、使用するターゲットオブジェクトとインターセプターの両方を渡す必要があります。メソッドは次のようになります。

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