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

歡迎訪問 生活随笔!

生活随笔

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

C#

【我们一起写框架】C#的AOP框架

發布時間:2023/12/6 C# 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【我们一起写框架】C#的AOP框架 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
原文:【我們一起寫框架】C#的AOP框架

前言

AOP,大家都是聽過的,它是一種面向切面的設計模式。

不過AOP雖然是被稱為設計模式,但我們應該很少能看到AOP設計的框架。為什么呢?

因為,AOP單獨設計的框架幾乎是無法使用的。普遍的情況是,AOP要是和其他設計模式結合在一起使用。

所以,AOP雖然是設計模式,但我認為它更接近一種設計元素,是我們在設計框架的作料。

其實AOP的原理就是將公共的部分提取出來,這件事,即便不考慮設計模式,每個開發人員在工作時也是會做的。也就是說,在AOP設計模式被提出來之前,我們就在應用AOP的設計了。

那么,為什么還要單獨將AOP拿出來說事呢?

我認為,主要目的應該是要強化切面的重要性。因為設計框架時加入AOP的理念,確實會讓框架更加立體。

AOP的應用

AOP既然是一種作料,那么它的應用就是多種多樣的;它可以出現在任何場合的。

下面我們舉出一個例子,來說明AOP的應用。

----------------------------------------------------------------------------------------------------

我們在開發的時候,通常會有這樣的需求。

[將函數的入參和返回值記錄到日志中][入參中為負數拋出異常]

當我們面對這樣的需求時,通常會將入參和返回值全部傳到一個獨立的操作函數中,對其進行相應的操作。

這樣實現,就是AOP的理念;不過開發者處理時,稍微繁瑣了一點,因為每個函數都要處理。

為了減少這種重復操作,讓我們一起來編寫函數的切面AOP吧。

AOP框架的實現

首先,我們一起看下AOP框架應用后的效果。

在下面代碼中,可以看到,我們定義了一個AOPTest類,然后調用了他的Test方法,之后傳入了一個正數和一個負數,如果函數拋出異常,我們將輸出異常的消息。

class Program {static void Main(string[] args){AOPTest test = new AOPTest();try{ test.Test(518);test.Test(-100);}catch(Exception ex){Console.WriteLine(ex.Message);}Console.ReadLine();} }

接下來我們看下AOPTest類的定義。

[Kiba] public class AOPTest : ContextBoundObject { public string Test(int para){Console.WriteLine(para);return "數字為:" + para;} }

代碼如上所示,很簡單,就是輸出了入參,不過有兩個地方需要注意,該類繼承了ContextBoundObject類,并且擁有一個KIba的特性。

然后,我們看下運行結果。

從運行結果中我們看到,第一個函數正常輸出,但第二個函數拋出了異常,而且異常的Message是異常兩個漢字。

這就是我們AOP實行的效果了,我們的AOP框架對函數入參進行了判斷,如果是正數,就正常運行,如果為負數就拋出異常。

下面我們一起來看看AOP框架是如何實現這樣的效果的。

首先我們一起來看下Kiba這個特性。

[AttributeUsage(AttributeTargets.Class)] public class KibaAttribute : ContextAttribute {public KibaAttribute(): base("Kiba"){} public override void GetPropertiesForNewContext(IConstructionCallMessage ctorMsg){ctorMsg.ContextProperties.Add(new KibaContextProperty()); } }

代碼如上所示,很簡單很基礎的一個特性,不過它繼承了ContextAttribute類,并重寫了其下的方法GetPropertiesForNewContext。

這個方法是干什么的呢?

我們可以從函數名的直譯來理解它是干什么的,GetPropertiesForNewContext直譯過來就是創建新對象時獲取他的屬性。然后我們看到,我們重新了該方法后又為他添加了一個新的屬性。

而我們添加的這個新的屬性將截獲擁有該特性的類的函數。

【PS:該描述并不是ContextAttribute真實的運行邏輯,不過,初學時,我們可以先這樣理解,當我們更深入的理解了函數的運行機制后,自然就明白該類的意義。】

?下面我們看下KibaContextProperty類。

public class KibaContextProperty : IContextProperty, IContributeObjectSink {public KibaContextProperty(){} public IMessageSink GetObjectSink(MarshalByRefObject obj, IMessageSink next){return new KibaMessageSink(next);} public bool IsNewContextOK(Context newCtx){return true;} public void Freeze(Context newCtx){} public string Name{get { return "Kiba"; }} }

代碼如上所示,依然很簡單,只是繼承并實現了IContextProperty和IContributeObjectSink兩個接口。

其中我們重點看下GetObjectSink方法,該方法用于截獲函數。

我們可以看到該方法的兩個參數,但我們只用到了一個IMessageSink ,并且,該方法的返回值也是IMessageSink。

所以,我們可以想到,該方法的本來面目是這樣的。

public IMessageSink GetObjectSink(MarshalByRefObject obj, IMessageSink next) {return next; }

也就是說,IMessageSink?封裝了函數的一切內容,那么我們的AOP實現的地方也就找到了。

于是我們用KibaMessageSink類處理一下IMessageSink 。

KibaMessageSink代碼如下:

public class KibaMessageSink : IMessageSink {private KAspec kaspec = new KAspec(); private IMessageSink nextSink; public KibaMessageSink(IMessageSink next){nextSink = next;} public IMessageSink NextSink{get{return nextSink;}} public IMessage SyncProcessMessage(IMessage msg){ IMethodCallMessage call = msg as IMethodCallMessage; if (call != null){//攔截消息,做前處理kaspec.PreExcute(call.MethodName, call.InArgs);}for (int i = 0; i < call.InArgs.Count(); i++){var para = call.InArgs[i];var type = para.GetType();string typename = type.ToString().Replace("System.Nullable`1[", "").Replace("]", "").Replace("System.", "").ToLower();if (typename == "int32"){int inparame = Convert.ToInt16(call.InArgs[i]);if (inparame < 0){throw new Exception("異常");}} }//傳遞消息給下一個接收器 IMessage retMsg = nextSink.SyncProcessMessage(call as IMessage); IMethodReturnMessage dispose = retMsg as IMethodReturnMessage;if (dispose != null){ //調用返回時進行攔截,并進行后處理kaspec.EndExcute(dispose.MethodName, dispose.OutArgs, dispose.ReturnValue, dispose.Exception);} return retMsg;} public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink){return null;} }

我們重點看下SyncProcessMessage方法。

可以看到,我們在方法調用先調用了KAspec類的PreExcute方法,該方法用于把入參輸出到日志中。

接下來,我們對入參進行了判斷,如果入參是負數,我們將不執行函數,直接拋出異常。

然后我們調用KAspec類的EndExcute方法,將返回值輸出到日志中。

再然后,我們才返回IMessage,讓函數完結。

下面我們一起看下KAspec類的實現。

/// <summary> /// 切面 /// </summary> public class KAspec { #region 處理/// <summary>/// 前處理/// </summary> public void PreExcute(string MethodName, object[] InParams){Logger.Info("==================== " + MethodName + ":" + " Start====================");Logger.Info(string.Format("參數數量:{0}", InParams.Count()));for (int i = 0; i < InParams.Count(); i++){Logger.Info(string.Format("參數序號[{0}] ============ 參數類型:{1} 執行類:{1}", i + 1, InParams[i])); Logger.Info("傳入參數:");string paramXMLstr = XMLSerializerToString(InParams[i], Encoding.UTF8);Logger.Info(paramXMLstr);}} /// <summary>/// 后處理/// </summary> public void EndExcute(string MethodName, object[] OutParams, object ReturnValue, Exception ex){Type myType = ReturnValue.GetType();Logger.Info(string.Format("返回值類型:{0}", myType.Name));Logger.Info("返回值:");if (myType.Name != "Void"){string resXMLstr = DataContractSerializerToString(ReturnValue, Encoding.UTF8);Logger.Info(resXMLstr);}if (OutParams.Count() > 0)//out 返回參數{Logger.Info(string.Format("out返回參數數量:{0}", OutParams.Count())); for (int i = 0; i < OutParams.Count(); i++){Logger.Info(string.Format("參數序號[{0}] == 參數值:{1}", i + 1, OutParams[i]));}}if (ex != null){Logger.Error(ex);}Logger.Info("==================== " + MethodName + ":" + " End====================");} }

代碼如上所示,就是簡單的日志輸出。

到此,我們的AOP框架就編寫完成了;其上的代碼編寫都是為KAspec服務,因為KAspec才是切面。

也就是說,只要將特性Kiba賦予給類,那么該類的函數,就被攔截監聽,然后我們就可以KAspec切面中,做我們想做的操作了。

最后,我們再回頭看下AOPTest類。

[Kiba] public class AOPTest : ContextBoundObject

可以看到,該類不止擁有Kiba特性,還繼承了ContextBoundObject類,該類是干什么的呢?

ContextBoundObject類是內容邊界對象,只有繼承了ContextBoundObject類的類,其類中才會駐留的Context上下文,并且會被ContextAttribute特性攔截監聽。

呃,其實,這樣解釋還是有點不太正確,不過我也沒找到更好的說明方式,如果你還理解不了,也可以去MSDN查詢下,當然,MSDN的解釋是反人類的,需要做好心理準備。

----------------------------------------------------------------------------------------------------

框架代碼已經傳到Github上了,歡迎大家下載。

Github地址:https://github.com/kiba518/KAOP

----------------------------------------------------------------------------------------------------

注:此文章為原創,歡迎轉載,請在文章頁面明顯位置給出此文鏈接!
若您覺得這篇文章還不錯,請點擊下右下角的推薦】,非常感謝!

?

總結

以上是生活随笔為你收集整理的【我们一起写框架】C#的AOP框架的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 超碰不卡 | 日本动漫艳母 | 色播一区二区 | 黄色日批网站 | 国产日韩在线观看一区 | 欧美黄色成人 | 男男啪啪无遮挡 | 美女试爆场恐怖电影在线观看 | 91在线观看欧美日韩 | 激情国产一区 | 日本女优一区 | 欧美午夜精品理论片a级按摩 | 国产偷自拍 | 一区二区三区中文视频 | 一区二区三区四区日韩 | 老司机午夜精品视频 | 性chinese天美传媒麻 | 黄色片免费在线播放 | 青青操视频在线 | 2018狠狠干 | 林天顾悦瑶笔趣阁 | 美女高潮在线 | 成人人人人人欧美片做爰 | 国产精品久久久国产盗摄 | 最新版天堂资源在线 | 亚洲成人av一区二区 | 免费毛片视频网站 | 国产三级三级看三级 | 午夜在线精品偷拍 | 亚洲一区免费 | 亚洲黄色片 | 亚洲一区久久 | 午夜影剧院| www.av欧美 | 久久久www成人免费精品 | 中国女人特级毛片 | 私人毛片 | 亚洲第一毛片 | 亚洲香蕉在线观看 | 波多野结衣一区二区三区高清av | 久久精品美女视频 | 在线中文字日产幕 | 综合久久国产 | 91亚洲影院 | 黄色长视频 | 已满十八岁免费观看 | 水密桃av | 国产精品久久国产精麻豆96堂 | 噜噜在线视频 | 日本成人在线网站 | 九色在线 | 亚洲精品久久久久久久久 | 国产精品一区二区在线免费观看 | 国产精品av免费观看 | 亚洲天天视频 | 韩国三级视频在线观看 | 日本免费黄色大片 | 亚洲yy| 国产suv精品一区二区33 | 国产亚洲精品成人无码精品网站 | 日日摸天天爽天天爽视频 | 久久特黄| av不卡免费在线观看 | 精品国产无码在线观看 | 国产免费又黄又爽又色毛 | 国产精久 | 男女啪动最猛动态图 | 亚洲av色一区二区三区精品 | 亚洲播放器 | 中文字幕一区二区三区在线视频 | 日韩欧美视频免费在线观看 | 日韩三级网 | 狠狠操网址 | 男女互操在线观看 | 超碰caopor | 日韩在线网 | 一区视频在线免费观看 | 高清不卡毛片 | 欧美69精品久久久久久不卡 | 超碰导航 | 3d动漫啪啪精品一区二区中文字幕 | 131美女爱做视频 | 国产熟女一区二区三区四区 | 色偷偷888欧美精品久久久 | 手机av免费 | 亚洲高清自拍 | 善良的公与媳hd中文字 | 成年人在线视频观看 | 狠狠狠狠狠狠狠干 | 国产女人18水真多18精品一级做 | 成人影片在线播放 | se日韩| 日本50路肥熟bbw| 欧美色图一区二区三区 | 亚洲乱码国产乱码精品精软件 | 欧美色射 | 九一国产在线 | 国产尤物av尤物在线看 | 伊伊综合网 |