互联网技术 · 2024年2月23日

使用AspectCore实现AOP的事务和缓存拦截器功能

这篇文章主要介绍了Asp.net Core 3.1基于AspectCore实现AOP实现事务、缓存*功能,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

最近想给我的框架加一种功能,就是比如给一个方法加一个事务的特性Attribute,那这个方法就会启用事务处理。给一个方法加一个缓存特性,那这个方法就会进行缓存。

这个也是网上说的面向切面编程AOP。

AOP的概念也很好理解,跟中间件差不多,说白了,就是我可以任意地在方法的前面或后面添加代码,这很适合用于缓存、日志等处理。

在net core2.2时,我当时就尝试过用autofac实现aop,但这次我不想用autofac,我用了一个更轻量级的框架,AspectCore。

用起来非常非常的简单,但一开始还是走了一点弯路,主要是网上都是net core3以下的教程,3以下的使用方法跟之前有一些不同。

先安装NuGet包,包名:AspectCore.Extensions.DependencyInjection

然后在Program.cs类中增加一行代码,这是net core 3的不同之处,这句添加的代码,意思就是用AspectCore的IOC容器替换内置的。因为AOP需要依靠IOC实现,所以必须得替换掉内置的IOC。

public class Program
  {
    public static void Main(string[] args)
    {
      CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
      Host.CreateDefaultBuilder(args)
      .ConfigureWebHostDefaults(webBuilder =>
      {
        webBuilder.UseStartup<Startup>();
      })
      //用AspectCore替换默认的IOC容器
      .UseServiceProviderFactory(new DynamicProxyServiceProviderFactory());
}

然后在Startup.cs类中的ConfigureServices中添加代码。(其实这个加不加都可以,如果需要配置就加,例如全局的*、只拦截哪些匹配的服务,因为我只用特性进行拦截,所以我就什么也没配置)

services.ConfigureDynamicProxy(o=> {
   //添加AOP的配置
});

这样AOP就配置好了,是不是很简单。

当然使用方面也需要注意一下,可以在接口、接口的方法、类,类的virtual方法上进行拦截。还有如果你想拦截控制器的action的话,那需要在ConfigureService里AddControllerAsServices

services.AddControllers()
//把控制器当成服务
.AddControllersAsServices()

下面我列出我的事务*代码,如果是特性拦截,就继承AbstractInterceptorAttribute,如果要写一个全局*,就AbstractInterceptor,然后在ConfigureDynamicProxy中进行配置,这个我就不介绍了

如果你的*是放在其他项目的,那要记得添加AspectCore.Core包,不要只添加AspectCore.Abstractions,我一开始就只添加了AspectCore.Abstractions,一直没发现IsAsync、UnwrapAsyncReturnValue等一些扩展方法。

public class TransactionInterceptorAttribute : AbstractInterceptorAttribute
  {
    public async override Task Invoke(AspectContext context, AspectDelegate next)
    {
      var dbContext = context.ServiceProvider.GetService<AppDbContext>();
      //先判断是否已经启用了事务
      if (dbContext.Database.CurrentTransaction == null)
      {
        await dbContext.Database.BeginTransactionAsync();
        try
        {
          await next(context);
          dbContext.Database.CommitTransaction();
        }
        catch (Exception ex)
        {
          dbContext.Database.RollbackTransaction();
     &nbsp

OpenMagic API

Need more than content? Move into the product flow.

If you are here for model access, pricing, developer docs, or the future API console, the dedicated product path now lives on api.openmagic.ai.

登录免费注册