mercredi 28 août 2019

AOP Interceptor feature with .NET Core

The Dependency Injection provider of .NETCore, out-of-the-box, doesn't provide Interceptors, as we can find in other DI frameworks as Unity or Spring.


I'm talking about intercept calls to methods not at Controllers levels, something we can do with Filters, Middlewares, etc, but for any service registered in the IServiceCollection, for that there is nothing available.

Using some techniques and based in a solid framework as Castle Windsor and DynamicProxy feature we can implement Interceptors for any class implementing an interface.

Nuget package: Castle.Core

public void ConfigureServices(IServiceCollection services)
{
services.AddTransientForInterception<IDataService, DataService>(sc => sc.InterceptBy<TInterceptorData>());
services.AddTransientForInterception<IExternalService, ExternalService>(sc => sc.InterceptBy<TInterceptorExternal>());
}
public interface IInterceptionRegistration
{
void InterceptBy<TInterceptor>() where TInterceptor : class, IInterceptor;
}
public class InterceptionRegistration : IInterceptionRegistration
{
//public TImp _Implementation;
public Type InterceptorType;
public InterceptionRegistration()
{
}
public void InterceptBy<TInterceptor>()
where TInterceptor : class, IInterceptor
{
InterceptorType = typeof(TInterceptor);
}
}
public static class ServiceCollectionExtensions
{
public static Dictionary<Type, Type> _interceptors = new Dictionary<Type, Type>();
public static void AddTransientForInterception<TInterface, TImplementation>(this IServiceCollection services,
Action<IInterceptionRegistration> configureInterceptor)
where TInterface : class where TImplementation : class, TInterface
{
services.AddTransient<TImplementation>();
var ci = new InterceptionRegistration();
configureInterceptor.Invoke(ci);
services.AddTransient(ci.InterceptorType);
services.AddTransient<TInterface>(sp =>
{
var implementation = sp.GetRequiredService<TImplementation>();
var interceptor = (IInterceptor)sp.GetRequiredService(ci.InterceptorType);
var proxyFactory = new ProxyGenerator();
return proxyFactory.CreateInterfaceProxyWithTarget<TInterface>(implementation, interceptor);
});
}
}
public class TInterceptorData : IInterceptor
{
public void Intercept(IInvocation invocation)
{
throw new System.NotImplementedException();
}
}
public class TInterceptorExternal : IInterceptor
{
public void Intercept(IInvocation invocation)
{
throw new System.NotImplementedException();
}
}
view raw aop-netcore hosted with ❤ by GitHub

Aucun commentaire:

Enregistrer un commentaire