日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

【代码设计】C# 实现 AOP 面向切面编程

發布時間:2025/3/8 C# 44 如意码农
生活随笔 收集整理的這篇文章主要介紹了 【代码设计】C# 实现 AOP 面向切面编程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

簡單記錄一下對AOP的認識,正文為3個部分

一、AOP由來

二、用DispatchProxy動態代理實現AOP

三、通過特性標記,處理多種不同執行前、執行后的邏輯編排

一、AOP 由來

    IUserHelper userHelper = new CommonUserHelper();
// commonUser.Create中存在 方法執行前、方法執行后的業務邏輯
userHelper.Create("test0401_A"); public interface IUserHelper
{
void Create(string name);
} public class CommonUserHelper : IUserHelper
{
private void before()
{
Console.WriteLine("CommonUser before");
} private void after()
{
Console.WriteLine("CommonUser after");
} public void Create(string name)
{
before();
Console.WriteLine($" Common User : {name} Created !");
after();
}
}

CommonUserHelper 實現 IUserHelper 接口,假設希望在 Create方法執行前/后寫入日志,那就存在這4種業務邏輯:

① 執行前寫入日志,執行 Create

② 執行前寫入日志,執行 Create,執行后寫入日志

③ 執行 Create,執行后寫入日志

④ 執行 Create

單一個寫日志的需求,就能有4種實現方式,極端情況下,是可以實現 4次 Create 方法;

如果再加一個數據驗證、IP驗證、權限驗證、異常處理、加入緩存..,那么實現的排列組合方式就更多了,

無窮盡地加實現、替換類,這顯然不是我們希望的。

AOP,Aspect Oriented Programing,是一種編程思維,是對這種缺陷的補充。

二、DispatchProxy (動態代理)實現AOP

using System.Reflection;
namespace Cjm.AOP
{
public class TransformProxy
{
public static T GetDynamicProxy<T>(T instance)
{
// DispatchProxy 是system.Reflection封裝的類
// 用以創建實現接口T的代理類CustomProxy的實例
dynamic obj = DispatchProxy.Create<T, CustomProxy<T>>();
obj.Instance = instance;
return (T)obj;
}
} // DispatchProxy 是抽象類,
// 實現該類的實例,實例方法執行是會跳轉到 Invoke 方法中,
// 以此達到不破壞實際執行的具體邏輯,而又可以在另外的地方實現執行前、執行后
public class CustomProxy<T> : DispatchProxy
{
public T Instance { get; set; }
protected override object? Invoke(MethodInfo? targetMethod, object?[]? args)
{
BeforeProcess();
var relt = targetMethod?.Invoke(Instance, args);
AfterProcess();
return relt;
} private void BeforeProcess()
{
Console.WriteLine($"This is BegoreProcess.");
} private void AfterProcess()
{
Console.WriteLine($"This is AfterProcess.");
}
}
} // Main
IUserHelper userHelper3 = new CommonUserHelper();
userHelper3 = TransformProxy.GetDynamicProxy(userHelper3);
userHelper3.Create("test0401_B");

三、通過標記特性,處理多種不同的執行前/執行后方法

此處借用Castle.Core的封裝(可通過Nuget管理下載),

通過實現 StandardInterceptor以重寫 執行前/執行后 邏輯的封裝方式,

我們可以更加聚焦在如何處理多種 執行前/執行后 邏輯的編排上。

using Castle.DynamicProxy;
{
ProxyGenerator proxy = new ProxyGenerator();
CustomInterceptor customInterceptor = new CustomInterceptor();
IUserHelper commonUserHelper = new CommonUserHelper();
var userHelperProxy = proxy.CreateInterfaceProxyWithTarget<IUserHelper>(commonUserHelper, customInterceptor);
userHelperProxy.Create("TEST0401_C");
}
    public class CustomInterceptor : StandardInterceptor
{
protected override void PreProceed(IInvocation invocation)
{
var method = invocation.Method;
//if (method.IsDefined(typeof(LogBeforeAttribute), true))
//{
// Console.WriteLine("LOG : CustomInterceptor.PreProceed");
//} Action<IInvocation> action = (invocation) => base.PreProceed(invocation);
// 獲取該方法的所有繼承BaseAOPAttribute的特性
var attrs = method.GetCustomAttributes<BaseAOPAttribute>(true);
// 對于 attrs 的排列順序,可以在特性的實現中增加 int order 屬性,在標記特性時寫入排序編號
foreach(var attr in attrs)
{
// 這里是俄羅斯套娃
// 相當于 attr3.AOPAction(invocation, attr2.AOPAction(invocation, attr1.AOPAction(invocation, base.PreProceed(invocation))))
action = attr.AOPAction(invocation, action);
}
action.Invoke(invocation);
} protected override void PerformProceed(IInvocation invocation)
{
Console.WriteLine("CustomInterceptor.PerformProceed");
base.PerformProceed(invocation);
} protected override void PostProceed(IInvocation invocation)
{
var method = invocation.Method;
if (method.IsDefined(typeof(LogAfterAttribute), true))
{
Console.WriteLine("LOG : CustomInterceptor.PostProceed");
} base.PreProceed(invocation);
}
}
    public class LogBeforeAttribute : Attribute {}

    public class LogAfterAttribute : Attribute {}

    public class CheckIPAttribute : BaseAOPAttribute
{
public override Action<IInvocation> AOPAction(IInvocation invocation, Action<IInvocation> action)
{
return (invocation) => {
Console.WriteLine("CheckIP ..");
action.Invoke(invocation);
};
}
} public abstract class BaseAOPAttribute : Attribute
{
public abstract Action<IInvocation> AOPAction(IInvocation invocation, Action<IInvocation> action);
}

通過給方法標記特性的方式,達到切面編程的目的(不影響原有實現,而增加實現執行前/執行后的邏輯)

    public interface IUserHelper
{
[LogBefore]
[LogAfter]
[CheckIP]
void Create(string name); void CreateNoAttri();
}

============================================================

具體的AOP實現上需要考慮的問題多如牛毛,此處僅做簡單的思路介紹。

以上主要參考自 B站 朝夕教育 2022 .Net Core AOP實現。

總結

以上是生活随笔為你收集整理的【代码设计】C# 实现 AOP 面向切面编程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。