.NET 静态代码织入 - 轻松实现 AOP

Rougamo 是什么

静态代码织入AOP,.NET最常用的AOP应该是Castle DynamicProxy,rougamo的功能与其类似,但是实现却截然不同, DynamicProxy是运行时生成一个代理类,通过方法重写的方式执行织入代码,rougamo则是代码编译时直接修改IL代码, .NET静态AOP方面有一个很好的组件PostSharp,rougamo的注入方式也是与其类似的。

6c76840faebc98f23ce442bc506581de.png

快速开始(MoAttribute)

// 1.NuGet引用Rougamo.Fody
// 2.定义类继承MoAttribute,同时定义需要织入的代码
public class LoggingAttribute : MoAttribute
{
    public override void OnEntry(MethodContext context)
    {
        // 从context对象中能取到包括入参、类实例、方法描述等信息
        Log.Info("方法执行前");
    }

    public override void OnException(MethodContext context)
    {
        Log.Error("方法执行异常", context.Exception);
    }

    public override void OnSuccess(MethodContext context)
    {
        Log.Info("方法执行成功后");
    }

    public override void OnExit(MethodContext context)
    {
        Log.Info("方法退出时,不论方法执行成功还是异常,都会执行");
    }
}

// 3.应用Attribute
public class Service
{
    [Logging]
    public static int Sync(Model model)
    {
        // ...
    }

    [Logging]
    public async Task<Data> Async(int id)
    {
        // ...
    }
}

根据方法可访问性批量应用

在上面介绍了如何将代码织入到指定方法上,但实际使用时,一个庞大的项目如果每个方法或很多方法都去加上这个Attribute 可能会很繁琐切侵入性较大。

所以MoAttribute设计为可以应用于方法(method)、类(class)、程序集(assembly)和模块(module), 同时设置了可访问性属性,增加灵活性。

// 1.在继承MoAttribute的同时,重写Flags属性,未重写时默认InstancePublic(public实例方法)
public class LoggingAttribute : MoAttribute
{
    // 改为所有public方法有效,不论是实例方法还是静态方法
    public override AccessFlags Flags => AccessFlags.Public;

    // 方法重写省略
}

// 2.应用
// 2.1.应用于类上
[Logging]
public class Service
{
    // Logging织入将被应用
    public static void M1() { }

    // Logging织入将被应用
    public void M2() { }

    // protected访问级别不会应用Logging的代码织入
    protected void M3() { }
}
// 2.2.应用于程序集上,该程序集所有public方法都将应用静态织入
[assembly: Logging]

重试功能

从1.4.0版本开始,可以在遇到指定异常或者返回值非预期值的情况下重新执行当前方法,实现方式是在OnException和OnSuccess中设置MethodContext.RetryCount值,在OnException和OnSuccess执行完毕后如果MethodContext.RetryCount值大于0那么就会重新执行当前方法。

这个功能有时候真是太方便了.

internal class RetryAttribute : MoAttribute
{
    public override void OnEntry(MethodContext context)
    {
        context.RetryCount = 3;
    }

    public override void OnException(MethodContext context)
    {
        context.RetryCount--;
    }

    public override void OnSuccess(MethodContext context)
    {
        context.RetryCount--;
    }
}

// 应用RetryAttribute后,Test方法将会重试3次
[Retry]
public void Test()
{
    throw new Exception();
}

项目地址

https://github.com/inversionhourglass/Rougamo

19ef7ed3a6f9a1dcd80ad2a84a9fd4d9.png

分享

4f5bf6767dda34315b3c9e33562407f9.png

点收藏 

18e9c8701944d657fc00e3ba55bbaa30.png

点点赞

bc52b4f2961d8c01b8f3077599bb5237.png

点在看

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值