Skip to content

miladj/ProxyGenerator

Repository files navigation

ProxyGenerator

This a simple proxy generator written in C#. It uses Dynamic class and ilgenerator to generate a near compile time class that can run as fast as possible.

ASP.NET Core

This a series of helper to help intercept and decorate service registered in the default aspnet core container. You have 2 option to intercept calls

  1. implement IInterceptor
  2. implement a Decorator class
public interface ISimple<T>
{
        string Test();
}
public class Simple<T> : ISimple<T>
{
    public string Test()
    {
        return "OK";
    }
}
public interface IService { }
public class Service:IService{}
public class SimpleDecorator<T> : ISimple<T>
{
    private readonly ISimple<T> _original;
    private IService _service;

    public SimpleDecorator(ISimple<T> original,IService service)
    {
        _service = service;
        _original = original;
    }

    public string Test()
    {
        return _original.Test();
    }
}
public class PassThroughInterceptor : IInterceptor
{
    public virtual object Intercept(IInvocation invocation, Func<object> next)
    {        
        return next();
    }
}
  1. using interceptor
services.AddSingleton(typeof(ISimple<>), typeof(Simple<>));
services.AddTransient<PassThroughInterceptor>();
services.Intercept(typeof(ISimple<>), typeof(PassThroughInterceptor));
  1. using decorator
services.AddTransient<IService, Service>();
services.AddTransient(typeof(ISimple<>), typeof(Simple<>));
services.Decorate(typeof(ISimple<>), typeof(SimpleDecorator<>));

General purpose proxy generator

There are two method to create proxy

  1. this one help you create a proxy with two parameter constructor (typeToProxy,IInterceptor[] )
ProxyMaker.CreateProxyType(Type typeToProxy)
  1. this one help you create a proxy that resolve types from IServicePrvider. this type has a constructor that accepts IServiceProvider
ProxyMakerAspnet.CreateProxyTypeWithInterceptors(Type typeToProxy, Type implementType,params Type[] interceptorTypes)

Interceptors

interceptors are called in a pipeline. and the action can be perform before and after the method. arguments and target can be changed by interceptors.

invocation.Target = new object();//Change target in interceptor
invocation.SetArgument(0,100); //change first argument of method
var argument=(int)invocation.GetArgument(0);//get first argument of method

Benchmarks

  1. call a method for a proxy generated object and an object generated by new keyword without any interceptor (just relay method calls)-Benchmark.
Method Mean Error StdDev
NonProxyCall 2.638 ns 0.0581 ns 0.0544 ns
ProxyCall 2.709 ns 0.0445 ns 0.0394 ns
WindsorProxyCall 27.660 ns 0.3050 ns 0.2853 ns
  1. call a method for a proxy generated object and an object generated by new keyword with interceptors-Benchmark.
Method Mean Error StdDev
CompileTimeProxyCall 11.58 ns 0.192 ns 0.170 ns
ProxyCall 31.39 ns 0.412 ns 0.385 ns
WindsorProxyCall 33.46 ns 0.280 ns 0.262 ns

Nuget

Install-Package ProxyGenerator.Core

Install-Package ProxyGenerator.Aspnet

Limitations

  1. no support for generic constraints.
  2. there is no cache for generated proxy.
  3. no support for ref, in, out method parameters.
  4. no support for changing arguments in interceptors.
  5. no support for changing target in runtime.
  6. mono doesn't work properly.

References

Scrutor

Castle Core