I would like to use DynamicObject derived types to execute REST API/NodeJS module calls. It would also help to capture API shape in a strictly typed manner, so here comes an interface proxy which hides low level machinery allowing to do tricks like this:
[TestMethod]
public void Call()
{
dynamic c = new ExpandoObject();
c.Add = (Func<int, int, int>)((a, b) => a + b);
ICalculator proxy = Proxy.Create<ICalculator>(c);
Assert.AreEqual(3, proxy.Add(1, 2));
}
public interface ICalculator
{
int Add(int a, int b);
}
Library code is:
using Castle.DynamicProxy;
using Dynamitey;
using System;
namespace Dynoproxy
{
public static class Proxy
{
public static T Create<T>(this object source) where T : class
{
var proxyGenerator = new ProxyGenerator();
return proxyGenerator.CreateInterfaceProxyWithoutTarget<T>(
ProxyGenerationOptions.Default,
new Interceptor(source));
}
class Interceptor : IInterceptor
{
public Interceptor(object target) => Target = target;
object Target { get; }
public void Intercept(IInvocation invocation) =>
invocation.ReturnValue = Dynamic.InvokeMember(
Target, invocation.Method.Name, invocation.Arguments);
}
}
}