Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to wrap existing object instance into DispatchProxy?

I'm looking for RealProxy replacement in .NET Core, and this issue forwards me to DispatchProxy.

It has simple API, but it's unclear, how to wrap existing object into proxy.
E.g., having this interface:

interface IFoo
{
    string Bar(int boo);
}

and this implementation:

class FooImpl : IFoo
{
    public string Bar(int boo)
    {
        return $"Value {boo} was passed";
    }
}

how to get what I want?

class Program
{
    static void Main(string[] args)
    {
        var fooInstance = new FooImpl();
        var proxy = DispatchProxy.Create<IFoo, FooProxy>();

        var s = proxy.Bar(123);

        Console.WriteLine(s);
    }
}

class FooProxy : DispatchProxy
{
    protected override object Invoke(MethodInfo targetMethod, object[] args)
    {
        return targetMethod.Invoke(/* I need fooInstance here */, args);
    }
}

Since DispatchProxy descendants must have parameterless constructor, the only idea I have is to invent some method, like this:

class FooProxy : DispatchProxy
{
    private object target;

    public void SetTarget(object target)
    {
        this.target = target;
    }

    protected override object Invoke(MethodInfo targetMethod, object[] args)
    {
        return targetMethod.Invoke(target, args);
    }
}

and use it this way:

var fooInstance = new FooImpl();
var proxy = DispatchProxy.Create<IFoo, FooProxy>();

((FooProxy)proxy).SetTarget(fooInstance);

// the rest of code...

Is this correct approach?

like image 281
Dennis Avatar asked Jul 05 '17 09:07

Dennis


1 Answers

You are right that there is no other option here than to cast the generated IFoo to the known proxy type (FooProxy) and use a custom method or property on FooProxy. There is no public API to add constructor arguments or return the proxy as the implementation type. However, DispatchProxy.Create() will return an instance of a subclass of FooProxy whose type is generated at runtime via reflection and IL emitting.

If you are looking at other ways to quickly wrap an implementation and replace interface methods / virtual methods, I suggest using mocking frameworks instead (FakeItEasy, Moq, NSubstitute etc.).

like image 60
Martin Ullrich Avatar answered Oct 04 '22 15:10

Martin Ullrich