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

歡迎訪問 生活随笔!

生活随笔

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

C#

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

發布時間:2025/3/8 C# 31 如意码农
生活随笔 收集整理的這篇文章主要介紹了 【代码设计】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 面向切面编程的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 国产一级视频在线 | 成人精品毛片 | 日韩伦理一区二区三区 | 香蕉在线播放 | 一区二区三区成人 | 青青操狠狠干 | 毛片88| 黄网www| 91久久久久久久久久久久久 | 日本成人午夜视频 | 午夜肉体高潮免费毛片 | 欧美亚洲精品天堂 | 亚洲一区二区三区四区在线播放 | 国产亚洲欧美精品久久久www | 亚洲一区二区视频在线播放 | 色婷婷国产精品综合在线观看 | 久久精品无码人妻 | 亚洲精品影片 | 国产一级二级三级在线观看 | 久久久久亚洲av无码网站 | 宅男在线视频 | 91麻豆产精品久久久久久 | 福利电影在线播放 | 黄色片免费在线播放 | 欧美一区二区日韩一区二区 | 国产日韩大片 | 福利一区福利二区 | www.日日日| 狠狠狠狠狠狠狠干 | 午夜性刺激免费视频 | 妖精视频一区二区三区 | 中文字幕一区二区av | 日韩精品一区二区三区色欲av | 亚洲偷自| 婷婷激情图片 | 羞羞的视频网站 | 欧美整片在线 | 求一个黄色网址 | 视频在线观看视频 | 韩日视频在线 | 亚洲成肉网 | 亚洲精品一区二区三区四区五区 | 欧美性生活一级 | 麻豆视频国产精品 | 成人av电影在线播放 | 色女综合 | 51精产品一区一区三区 | 国产aⅴ精品一区二区三区久久 | 久久午夜无码鲁丝片午夜精品 | 国产黄色免费网站 | 麻豆免费观看视频 | 色综合中文 | 国产免费一区二区三区最新不卡 | 97在线精品视频 | 日本免费成人 | 国产精品无码一区二区三区 | 99热这里只 | 亚洲国产日韩在线一区 | 黄色一级国产 | 国产午夜精品一区二区理论影院 | 超碰在线观看99 | 97视频人人 | 韩日精品中文字幕 | 亚a在线| 国产男女自拍 | 久久av一区二区三区漫画 | 在线观看麻豆视频 | 国产精品videossex久久发布 | 亚洲欧洲视频在线观看 | 黄黄视频在线观看 | 成人免费一区二区三区 | 快色网站 | 日本成人a | 公与妇乱理三级xxx www色 | zzjj国产精品一区二区 | 男女那个视频 | 亚洲高清色 | 一区二区三区精品在线 | 国产精品久久777777毛茸茸 | 无码不卡av东京热毛片 | 国产精品久久久久久99 | 一区二区三区四区中文字幕 | 男生操女生网站 | 中文字幕乱码亚洲无线三区 | 精品福利视频一区二区 | 粉嫩小箩莉奶水四溅在线观看 | 黄色片网站免费在线观看 | 91久久精品一区二区 | 亚洲乱码国产乱码精品天美传媒 | 好吊色视频一区二区三区 | 艳母日本动漫在线观看 | 亚洲黄色免费视频 | 欧美日韩一区免费 | 香蕉视频官方网站 | 国产女人视频 | av首页在线观看 | 天天摸日日 | 中国大陆一级毛片 | 欧美极度另类 |