.Net Core3.x中的AOP框架-AspectCore

在之前,我有记录到.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,那么这个FilterInterceptors有什么区别呢?我们来对比一下。新建一个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更好一些。

You forgot to set the qrcode for Alipay. Please set it in _config.yml.
You forgot to set the qrcode for Wechat. Please set it in _config.yml.
You forgot to set the business and currency_code for Paypal. Please set it in _config.yml.
You forgot to set the url Patreon. Please set it in _config.yml.
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×