在asp.net mvc或asp.net miniapi中,有过滤器,可以在请求前或后增加一层,达到验证,过滤等作用,如果在Service的方法前后加一层呢?这里介绍一下Castle.DynamicProxy的用法。
首先引入
Castle.Core
实现代码相对轻量:
using Castle.DynamicProxy;
using Microsoft.Extensions.DependencyInjection.Extensions;var builder = WebApplication.CreateBuilder(args);
builder.Services.AddInterceptedSingleton<ITestService, TestService, AddLogInterceptor>();var app = builder.Build();app.MapGet("/test", (ITestService test) =>
{app.Logger.LogInformation("/test开始");var result = test.Get(121);app.Logger.LogInformation("/test结束");return result;
});app.Run();public interface ITestService
{string Get(int id);
}
public class TestService : ITestService
{private readonly ILogger<TestService> _logger;public TestService(ILogger<TestService> logger){_logger = logger;}public string Get(int id){_logger.LogInformation("TestService.Get({id})", id);return "OK";}
}
public class AddLogInterceptor : IInterceptor
{private readonly ILogger<AddLogInterceptor> _logger;public AddLogInterceptor(ILogger<AddLogInterceptor> logger){_logger = logger;}public void Intercept(IInvocation invocation){//用invocation可以获取被调用对象和方法的信息_logger.LogInformation("开始调用{name},参数:{args}", invocation.Method.Name, string.Join(",", invocation.Arguments));invocation.Proceed();_logger.LogInformation("结束调用{name},返回结果:{result}", invocation.Method.Name, invocation.ReturnValue);}
}
public static class InterceptedExpansion
{public static void AddInterceptedSingleton<TIService, TService, TInterceptor>(this IServiceCollection services)where TIService : classwhere TService : class, TIServicewhere TInterceptor : class, IInterceptor{services.TryAddSingleton<IProxyGenerator, ProxyGenerator>();services.AddSingleton<TService>();services.TryAddTransient<TInterceptor>();services.AddSingleton(provider =>{var proxyGenerator = provider.GetRequiredService<IProxyGenerator>();var service = provider.GetRequiredService<TService>();var interceptor = provider.GetRequiredService<TInterceptor>();return proxyGenerator.CreateInterfaceProxyWithTarget<TIService>(service, interceptor);});}
}
效果如下: