3

インターフェイス IFoo があるとしましょう

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

任意の IFoo オブジェクトを受け取り、実際の呼び出しの前後に何かを行うラッパーを作成できますか?

たとえば、私がこのようなことをするとき

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

4 に答える 4

0

このアプローチにはコード コントラクトを使用できます。ユーザーマニュアル(pdf)のセクション2.8 Interface Contractsをご覧ください。

于 2013-04-09T03:01:02.813 に答える
0

AOP を使用できます。私はかなり長い間このライブラリを使用しています:

http://www.postsharp.net/products

于 2013-04-09T03:11:29.420 に答える
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();

もちろん、メソッドPrecallとメソッドがジェネリックでない場合、そのクラスPostcallを使用しても意味がありません。Wrapper<T>と一緒に行くだけFooWrapperです。

于 2013-04-09T04:25:40.040 に答える
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()

于 2013-04-09T04:05:33.737 に答える