在之前,我有记录到.Net Core 3.x 使用Autofac替换默认Ioc容器,这里,我们就来学习一下.Net Core中如何实现AOP
由于之前用到了Autofac
,所以这里就结合Autofac
来使用AspectCore
,首先需要引入AspectCore.Extensions.Autofac
,我们新建一个名为MethodExecuteLoggerInterceptor
的类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class MethodExecuteLoggerInterceptor : AbstractInterceptor { public override async Task Invoke(AspectContext context, AspectDelegate next) { var stopwatch = Stopwatch.StartNew(); await next(context); stopwatch.Stop(); Console.WriteLine("Executed method {0}.{1}.{2} ({3}) in {4}ms", context.ImplementationMethod.DeclaringType.Namespace, context.ImplementationMethod.DeclaringType.Name, context.ImplementationMethod.Name, context.ImplementationMethod.DeclaringType.Assembly.GetName().Name, stopwatch.ElapsedMilliseconds ); } }
|
在我们之前的WebModule
中加入一下代码进行注册
1 2 3
| builder.RegisterDynamicProxy(config=> { config.Interceptors.AddTyped<MethodExecuteLoggerInterceptor>(Predicates.ForService("*Service")); });
|
全局拦截带有Service
后缀的类,
此时在启动起来,使用Swagger来调用我们的Web Api,会看到打印出MethodExecuteLoggerInterceptor
里面的信息:
1
| Executed method Web.Services.ExampleService.GetName (Web) in 114ms
|
在.net core中,也有Filter
,那么这个Filter
和Interceptors
有什么区别呢?我们来对比一下。新建一个ExecuteLoggerFilter
,在.net corehttps://github.com/dotnet/aspnetcore/tree/master/src/Mvc/Mvc.Abstractions/src/Filters中提供多种Filter
接口,如:IActionFilter
,IAuthorizationFilter
,IExceptionFilter
,IResultFilter
,IResourceFilter
等,这里我们让新建类继承IActionFilter
,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class ExecuteLoggerFilter : IActionFilter { Stopwatch stopwatch = null; public void OnActionExecuted(ActionExecutedContext context) { stopwatch.Stop(); Console.WriteLine("Filter 执行完毕"); Console.WriteLine("Filter Executed {0}ms", stopwatch.ElapsedMilliseconds); }
public void OnActionExecuting(ActionExecutingContext context) { stopwatch = Stopwatch.StartNew(); Console.WriteLine("Filter 开始执行"); } }
|
我在注册到Ioc中
1 2 3
| services.AddControllers(options=> { options.Filters.Add<ExecuteLoggerFilter>(); });
|
我们可以看到这样的顺序:
1 2 3 4 5 6
| Filter 开始执行 开始执行AOP AOP Over Executed method Web.Services.ExampleService.GetName (Web) in 12ms Filter 执行完毕 Filter Executed 137ms
|
Filter会比我们的AOP粒度更大一些。一般粗粒度的可以用Filter
来处理就可以了,如果想更细粒度的如到action
的话,采用AOP更好一些。