ABP框架9——自定义拦截器的实现与使用
一、AOP编程
- AOP定义:面向切片编程,着重强调功能,将功能从业务逻辑分离出来。
- AOP使用场景:处理通用的、与业务逻辑无关的功能(如日志记录、性能监控、事务管理等)
- 拦截器:拦截方法调用并添加额外的行为,比如日志记录、权限检查等
- 拦截器是 AOP 编程的一种实现方式
二、拦截器在ABP框架中的写法位置
1.在应用层-拦截器文件夹编写拦截器
2.在应用层-相应模块类注册拦截器
三、版本一(不推荐,ABP封装拦截器)
不推荐是因为很多功能都不支持,比如说查特性、查路由、接口名称等,不过捕捉日志还是可以的!
1.应用层
using Acme.BookStore.Books;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.DynamicProxy;
namespace Acme.BookStore.Interceptor
{
//应用层
public class AopInterceptor : AbpInterceptor, ITransientDependency
{
public override async Task InterceptAsync(IAbpMethodInvocation invocation)
{
try
{
//入参
var arguments = invocation.Arguments;
// 在方法执行前输出日志
Trace.WriteLine($"【调用方法】: {invocation.Method.Name},【时间】{DateTime.Now},【入参】: {string.Join(",", arguments)}");
// 继续执行原方法
await invocation.ProceedAsync();
var returnValue = invocation.ReturnValue;
// 在方法执行后输出日志
Trace.WriteLine($"方法执行完成,出参数【{returnValue}】");
}
catch (Exception ex)
{
// 模拟捕捉错误并输出日志
Trace.WriteLine($"方法 {invocation.Method.Name} 执行发生错误: {ex.Message}, {DateTime.Now}");
}
}
}
}
2.模块类
using Acme.BookStore.Interceptor;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using System;
using System.Diagnostics;
using System.Linq;
using Volo.Abp.Account;
using Volo.Abp.AutoMapper;
using Volo.Abp.DependencyInjection;
using Volo.Abp.DynamicProxy;
using Volo.Abp.FeatureManagement;
using Volo.Abp.Identity;
using Volo.Abp.Json;
using Volo.Abp.Json.SystemTextJson;
using Volo.Abp.Modularity;
using Volo.Abp.PermissionManagement;
using Volo.Abp.SettingManagement;
using Volo.Abp.TenantManagement;
using Volo.Abp.Uow;
namespace Acme.BookStore;
[DependsOn(
typeof(BookStoreDomainModule),
typeof(AbpAccountApplicationModule),
typeof(BookStoreApplicationContractsModule),
typeof(AbpIdentityApplicationModule),
typeof(AbpPermissionManagementApplicationModule),
typeof(AbpTenantManagementApplicationModule),
typeof(AbpFeatureManagementApplicationModule),
typeof(AbpSettingManagementApplicationModule)
)]
public class BookStoreApplicationModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpAutoMapperOptions>(options =>
{
options.AddMaps<BookStoreApplicationModule>();
});
// 注册拦截器
context.Services.OnRegistred(ctx =>
{
if (ctx.Interceptors.Any())
{
ctx.Interceptors.TryAdd<AopInterceptor>();
}
});
}
}
四、版本二(推荐 MVCcore过滤器)
1.应用层
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Diagnostics;
using System.Linq;
using Volo.Abp.DependencyInjection;
namespace Acme.BookStore.Interceptor
{
//应用层
public class AopInterceptor : IActionFilter, ITransientDependency
{
/// <summary>
/// 请求之前
/// </summary>
/// <param name="context"></param>
public void OnActionExecuting(ActionExecutingContext context)
{
//方法名称
var methodName = (context.ActionDescriptor as ControllerActionDescriptor)?.ActionName;
// 特性
var arrt = context.ActionDescriptor.EndpointMetadata.OfType<Attribute>();
//判断是否含有某个特性标签
bool hasMyCustomAttribute = arrt.Any(attr => attr.GetType() == typeof(AopAttribute));
Trace.WriteLine($"执行前:【路由】{context.ActionDescriptor.AttributeRouteInfo?.Template},【方法】{methodName},【入参】{context?.ActionArguments},【特性】{arrt},【请求方式】{context.HttpContext.Request.Method}");
}
/// <summary>
/// 请求之后
/// </summary>
/// <param name="context"></param>
public void OnActionExecuted(ActionExecutedContext context)
{
var res = context.Result as ObjectResult;
Trace.WriteLine($"执行后:【出参】{res?.Value}");
}
}
/// <summary>
/// 自定义特性标签(可选)
/// </summary>
[AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Method)]
public class AopAttribute : Attribute { }
}
2.模块类
using Acme.BookStore.Interceptor;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Account;
using Volo.Abp.AutoMapper;
using Volo.Abp.FeatureManagement;
using Volo.Abp.Identity;
using Volo.Abp.Json;
using Volo.Abp.Modularity;
using Volo.Abp.PermissionManagement;
using Volo.Abp.SettingManagement;
using Volo.Abp.TenantManagement;
namespace Acme.BookStore;
[DependsOn(
typeof(BookStoreDomainModule),
typeof(AbpAccountApplicationModule),
typeof(BookStoreApplicationContractsModule),
typeof(AbpIdentityApplicationModule),
typeof(AbpPermissionManagementApplicationModule),
typeof(AbpTenantManagementApplicationModule),
typeof(AbpFeatureManagementApplicationModule),
typeof(AbpSettingManagementApplicationModule)
)]
public class BookStoreApplicationModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpAutoMapperOptions>(options =>
{
options.AddMaps<BookStoreApplicationModule>();
});
// 注册拦截器
context.Services.AddMvcCore(x=> x.Filters.Add<AopInterceptor>());
}
}