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.
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
- implement
IInterceptor
- 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();
}
}
- using interceptor
services.AddSingleton(typeof(ISimple<>), typeof(Simple<>));
services.AddTransient<PassThroughInterceptor>();
services.Intercept(typeof(ISimple<>), typeof(PassThroughInterceptor));
- using decorator
services.AddTransient<IService, Service>();
services.AddTransient(typeof(ISimple<>), typeof(Simple<>));
services.Decorate(typeof(ISimple<>), typeof(SimpleDecorator<>));
There are two method to create proxy
- this one help you create a proxy with two parameter constructor (typeToProxy,IInterceptor[] )
ProxyMaker.CreateProxyType(Type typeToProxy)
- this one help you create a proxy that resolve types from
IServicePrvider
. this type has a constructor that acceptsIServiceProvider
ProxyMakerAspnet.CreateProxyTypeWithInterceptors(Type typeToProxy, Type implementType,params Type[] interceptorTypes)
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
- 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 |
- 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 |
Install-Package ProxyGenerator.Core
Install-Package ProxyGenerator.Aspnet
- no support for generic constraints.
- there is no cache for generated proxy.
no support for ref, in, out method parameters.no support for changing arguments in interceptors.no support for changing target in runtime.- mono doesn't work properly.