3

Let's say I have an interface IFoo

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

Can I create a wrapper that takes any IFoo object and do something before/after the actual call?

e.g. when I do something like this

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

then the wrapper.Bar() method actually execute something like this

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

Is there a simple and clean way to do this?

Louis Rhys
  • 34,517
  • 56
  • 153
  • 221
  • `Wrapper` doesn't make much sense to me, since you want to be able to write `wrapper.Bar()`...all these methods must therefore be defined in `Wrapper`, but they are `T`-specific. Seems to me that you need to make `IFooWrapper` implement `IFoo`, and do so for each interface. That would mean to write the same `Precall(); object.Bar; Postcall()` for all `Bar` methods, which is not simple and clean :-) – Julián Urbano Apr 09 '13 at 03:16
  • @caerolus you're right, Wrapper doesn't make sense. Maybe we can still keep the generic-ness by defining `T Object { get; }` property for `Wrapper`, similar to `mock.Object` in `Moq`. – Louis Rhys Apr 09 '13 at 03:37
  • But doing something like `IFoo wrappedFoo = new Wrapper(actualFooObject).Object;` you're just ignoring the wrapper... `wrappedFoo` would just point to the original object! – Julián Urbano Apr 09 '13 at 03:43
  • This might be useful as well http://stackoverflow.com/questions/1920222/automatically-creating-a-wrapper-to-implement-an-interface?rq=1 and this too http://stackoverflow.com/questions/847809/how-can-i-write-a-generic-container-class-that-implements-a-given-interface-in-c/847975#847975 – Julián Urbano Apr 09 '13 at 04:31
  • @caerolus not necessarily, the property object can return something else (not the original object) – Louis Rhys Apr 09 '13 at 05:09

4 Answers4

0

You can use Code Contracts for this approach. Take a look on section 2.8 Interface Contracts of user manual (pdf).

outcoldman
  • 11,584
  • 2
  • 26
  • 30
  • you mean instead of defining contract, I can write my custom code in the contract class? – Louis Rhys Apr 09 '13 at 03:05
  • Sorry, I actually forgot that they are really primitive.. You can try to write your own contracts and override defaults, but anyway this will be really primitive. – outcoldman Apr 09 '13 at 05:28
0

You can use AOP. I´ve been using this library for quite some time now:

http://www.postsharp.net/products

MeTitus
  • 3,390
  • 2
  • 25
  • 49
0

if you need to have something on PreCall() and PostCall , the simple way is to wrap under the proxy base approach

  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();

    }
  }

--------------- Output --------------
ProxyBase.PreCondition()
AppProxy.Call()
ActualFoo.Call()
ProxyBase.PreCondition()

Turbot
  • 5,095
  • 1
  • 22
  • 30
0

I don't see a "clean and simple" way of doing this.

The best option I can come up with is writing a generic Wrapper<T> that encapsulates and instance of T and implements generic Precall and Postcall methods:

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
    }
}

So that you can write your own FooWrapper for interface IFoo (or any other interface) and just delegate method calls:

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();
    }
}

So you can use it like this:

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

Of course, if your Precall and Postcall methods are not generic, then there is really no point in using the Wrapper<T> class. Just go with the FooWrapper.

Julián Urbano
  • 8,378
  • 1
  • 30
  • 52