AOP编程

这里是 csharp 的 AOP 笔记

安装 Rougamo.Fody 后编写 TimingAttribute, 放到 Method 上就生效了

csharp

using System.Diagnostics;
using Rougamo;
using Rougamo.Context;
using Serilog;

namespace Uni.Webapi.Common;

public class TimingAttribute : MoAttribute
{
    private readonly Stopwatch _stopwatch = new();

    public override void OnEntry(MethodContext context)
    {
        // OnEntry对应方法执行前
        _stopwatch.Start();
    }

    public override void OnException(MethodContext context)
    {
        // OnException对应方法抛出异常后
    }

    public override void OnSuccess(MethodContext context)
    {
        // OnSuccess对应方法执行成功后
    }

    public override void OnExit(MethodContext context)
    {
        // OnExit对应方法退出时
        _stopwatch.Stop();
        Log.Information($"{context.Method.Name} 耗时:{_stopwatch.ElapsedMilliseconds}ms");
    }
}

// 定义一个类型继承AsyncMoAttribute
// public class TestAttribute : AsyncMoAttribute
// {
//     public override async ValueTask OnEntryAsync(MethodContext context) { }
//
//     public override async ValueTask OnExceptionAsync(MethodContext context) { }
//
//     public override async ValueTask OnSuccessAsync(MethodContext context) { }
//
//     public override async ValueTask OnExitAsync(MethodContext context) { }
// }
  • AspectCore-Framework
    • 编写 CustomInterceptorAttribute
    • 添加服务 services.ConfigureDynamicProxy();
    • 替换容器 Host.CreateDefaultBuilder(args).UseServiceProviderFactory(new DynamicProxyServiceProviderFactory())
  • Autofac-DI配置 , AOP配置
    • 创建 public class CallLogger : IInterceptor
    • 注册拦截器 builder.Register(c => new CallLogger(Console.Out));
    • 注册服务的时候启用拦截器 builder.registerType().EnableInterfaceInterceptors()
    • 在接口和 class 上配置 [Intercept(typeof(CallLogger))] , 不能用在函数上, 默认拦截接口/class 的所有方法
    • 替换容器 Host.CreateDefaultBuilder(args).UseServiceProviderFactory(new AutofacServiceProviderFactory())