天天看點

.NET 靜态代碼織入 - 輕松實作 AOP

作者:opendotnet

Rougamo 是什麼

靜态代碼織入AOP,.NET最常用的AOP應該是Castle DynamicProxy,rougamo的功能與其類似,但是實作卻截然不同, DynamicProxy是運作時生成一個代理類,通過方法重寫的方式執行織入代碼,rougamo則是代碼編譯時直接修改IL代碼, .NET靜态AOP方面有一個很好的元件PostSharp,rougamo的注入方式也是與其類似的。

.NET 靜态代碼織入 - 輕松實作 AOP

快速開始(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

.NET 靜态代碼織入 - 輕松實作 AOP

分享

.NET 靜态代碼織入 - 輕松實作 AOP

點收藏

.NET 靜态代碼織入 - 輕松實作 AOP

繼續閱讀