0

I have a class A that implements interface IA:

class A : IA
{
   f(){...}
}

I want to wrap A using a new class WrapA that will implement IA as well, with the intention of wrapping A by calling each one of its functions as a new task:

class WrapA : IA
{
  private A;
  f()
  {
    StartInNewTask(A.f());
  }
}

Of course this is very easy to do manually.

But I want an automatic mechanism for this wrapping, similar to the one mocks use to mock interfaces.

If it was done before I would love to see an example, or any idea on how to implement it.

Mugen
  • 8,301
  • 10
  • 62
  • 140

2 Answers2

1

To achieve this, you can use CodeDOM, a technology to dynamically create code. You construct your namespace/class in an object-oriented way. See MSDN CodeDOM for detailed documentation.

In your case, you would need to read the methods you want to wrap via reflection, using the Type.GetMethods-Method. Thus, you access the target-methods using a CodeMethodInvokeExpression. You need to have a reference to the wrapped object, which you can access using a CodeVariableReferenceExpression. With that, you can use the CodeMethodInvokeExpression to invoke the Task.Run()-Method (or whatever you use) and provide the Delegate and the reference to your target-object.

It is a bit of a complex topic, so you will need to read some documentation, but since it's a Microsoft technology it is very well documented feature. Once you have read it, it will be pretty easy to implement your wrapper.

Patrik
  • 1,355
  • 12
  • 22
0

I found that the best framework was Unity's interceptors.

Since I already used Unity Bootstrapper, it was quite easy to integrate.

https://msdn.microsoft.com/en-us/library/dn178466%28v=pandp.30%29.aspx

The implementation (simplified, you will need to be careful with the return value):

public class RestPerformanceInterceptor : IInterceptionBehavior
{
    public bool WillExecute { get { return true; } }

    public IEnumerable<Type> GetRequiredInterfaces()
    {
        return new[] { typeof(IA) };
    }

    public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
    {
        var behaviorDelegate = getNext();

        StartInNewTask(behaviorDelegate.Invoke(input, getNext));

        return new Mock<IMethodReturn>();
    }
}
Mugen
  • 8,301
  • 10
  • 62
  • 140