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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} |
Aucun commentaire:
Enregistrer un commentaire