我可以创建一个包装器来拦截对实现某些接口的对象的所有调用吗?

时间:2013-04-09 02:54:43

标签: c# .net methods interface

假设我有一个接口IFoo

interface IFoo
{
  int Bar();
  int Bar2();
  void VBar();
  //etc,
}

我可以创建一个包含任何IFoo对象的包装器并在实际调用之前/之后执行某些操作吗?

e.g。当我做这样的事情时

IFoo wrappedFoo = new Wrapper<IFoo>(actualFooObject).Object;
wrappedFoo.Bar();

然后wrapper.Bar()方法实际执行类似这样的东西

PreCall(); //some code that I can define in the wrapper
actualFooObject.Bar();
PostCall();

有一种简单而干净的方法吗?

4 个答案:

答案 0 :(得分:0)

您可以使用Code Contracts来实现此方法。请查看user manual2.8 Interface Contracts部分(pdf)。

答案 1 :(得分:0)

您可以使用AOP。我已经使用这个库很长一段时间了:

http://www.postsharp.net/products

答案 2 :(得分:0)

如果你需要在PreCall()PostCall上拥有一些东西,那么简单的方法是在代理基础方法下进行包装

  public abstract class ProxyBase
  {
    public void Execute()
    {
      PreCondition();
      Call();
      PostCondition();
    }
    private void PreCondition()
    {
      Console.WriteLine("ProxyBase.PreCondition()");
    }
    private void PostCondition()
    {
      Console.WriteLine("ProxyBase.PreCondition()");
    }
    protected abstract void Call();
  }
  public class AppProxy<T> : ProxyBase where T : IApp
  {
    private IApp _app;

    public AppProxy<T> Init(IApp app)
    {
      _app = app;
      return this;
    }

    protected override void Call()
    {
      Console.WriteLine("AppProxy.Call()");
      _app.Call();
    }

    public IApp Object
    {
      get { return _app; }
    }
  }

  public interface IApp
  {
    void Call();
  }

  public interface IFoo : IApp
  {

  }

  public class ActualFoo : IApp
  {
    public void Call()
    {
      Console.WriteLine("ActualFoo.Call()");
    }
  }

 class Program
  {
    static void Main(string[] args)
    {
      ActualFoo actualFoo = new ActualFoo();
      var app = new AppProxy<IFoo>().Init(actualFoo);
      app.Execute();
      var o = app.Object as ActualFoo;

      Console.ReadLine();

    }
  }

---------------输出--------------
ProxyBase.PreCondition()
AppProxy.Call()
ActualFoo.Call()
ProxyBase.PreCondition()

答案 3 :(得分:0)

我没有看到“干净简单”的做法。

我能提出的最佳选择是编写一个通用的Wrapper<T>,它封装了T的实例并实现了通用的PrecallPostcall方法:

public class Wrapper<T>
{
    protected T _instance;
    public Wrapper(T instance)
    {
        this._instance = instance;
    }
    protected virtual void Precall()
    {
        // do something
    }
    protected virtual void Postcall()
    {
        // do something
    }
}

这样您就可以为接口FooWrapper(或任何其他接口)编写自己的IFoo,并只委派方法调用:

public class FooWrapper :Wrapper<IFoo>, IFoo
{
    public FooWrapper(IFoo foo)
        : base(foo)
    {
    }
    public int Bar()
    {
        base.Precall(); return base._instance.Bar(); base.Postcall();
    }
    public int Bar2()
    {
        base.Precall(); return base._instance.Bar2(); base.Postcall();
    }
    public void VBar()
    {
        base.Precall();  base._instance.VBar(); base.Postcall();
    }
}

所以你可以像这样使用它:

IFoo f = new ActualFooClass();
IFoo wf = new FooWrapper(f);
f.Bar();

当然,如果您的PrecallPostcall方法不是通用的,那么使用Wrapper<T>类就没有意义了。只需使用FooWrapper