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?
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 onFooProxy
. 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 ofFooProxy
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.).
You need to create your own Generic class that inherit from DispatchProxy and has own static Create that has an extra parameter from type target.
example
to use your example