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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

特性与方法注入

發布時間:2025/7/14 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 特性与方法注入 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
好久沒寫文章了,主要是前面一段時間比較忙,一直沒空學習和思考,好不容易找了個休息日,寫一下Blog
??? 前幾篇已經寫到過特性,并且用它實現了一些東西。這次來談一下一種比較怪異的特性的運用——方法注入。
??? 其實,說他怪異,稍微過了點,因為就連M$給大家的類庫就用這種運用,舉個例子TransactionAttribute,就是一個對事務相關方法的一個行為指導的注入。為什么這么說,TransactionAttribute可以定義強制開始一個新的事務或者使用已經存在的事務,或者定義事務的隔離級別。但是,特性本身什么事情也不能做,必須由別的類來讀去這個特性,由別的類根據這個特性做某些事,TransactionAttribute為什么會起作用?原因是在事務處理時,處理函數會創建一個StackTrace,通過查找當前堆棧上的方法的TransactionAttribute,獲得相關的事務信息,通過這些,事務處理函數就以期望的方式工作了。(因為特性標記在某個直接或間接調用到事務的方法上,所以執行事務的時候,這個方法一定在這個堆棧上)
??? 利用這個原理,可以做出一種類似的,利用特性注入方法的方式。這里就以最簡單的驗證參數為例:
????1、創建一個驗證特性,作為所有驗證特性的基類:
????public?abstract?class?ValidateAttribute?:?Attribute
????
{
????????
protected?ValidateAttribute()?{?}

????????
public?abstract?void?Validate(object?value);
????}


????2、創建一個過濾空引用的驗證特性:
????[AttributeUsage(AttributeTargets.Method,?AllowMultiple?=?false,?Inherited?=?false)]
????
public?sealed?class?NonNullValidateAttribute
????????:?ValidateAttribute
????
{

????????
public?NonNullValidateAttribute()
????????????:?
base()?{?}
????????
????????
public?override?void?Validate(object?value)
????????
{
????????????
if?(value?==?null)
????????????????
throw?new?ArgumentNullException();
????????}


????}


????3、下一步,創建一個驗證方法:
????public?static?class?Validator
????
{
????????
public?static?void?Validate(object?value)
????????
{
????????????StackFrame?sf?
=?new?StackFrame(1,?false);
????????????MethodBase?m?
=?sf.GetMethod();
????????????
object[]?attrs?=?m.GetCustomAttributes(typeof(ValidateAttribute),?false);
????????????
foreach?(ValidateAttribute?attr?in?attrs)
????????????
{
????????????????attr.Validate(value);
????????????}

????????}

????}


????4、用起來看看吧
????????static?object?_testField;

????????
static?void?Main(string[]?args)
????????{
????????????
try
????????????{
????????????????TestProp?
=?null;
????????????????Console.WriteLine(TestProp);
????????????}
????????????
catch?(Exception?ex)
????????????{
????????????????Console.WriteLine(ex.Message);
????????????}
????????????Console.ReadLine();
????????}

????????
static?object?TestProp
????????{
????????????
get?{?return?_testField;?}
????????????[NonNullValidate()]
????????????
set
????????????{
????????????????Validator.Validate(value);
????????????????_testField?
=?value;
????????????}
????????}

????跑起來看看,看到了什么?對了ArgumentNullException的默認Message,Validator.Validate并沒有任何顯式的拋出這個異常,那么為什么會檢測出這個空參數哪?
????原因在于Validator.Validate檢查了當前調用堆棧中前一個方法(當前方法就是Validator.Validate自身),也就是調用Validator.Validate方法的方法,讀去這個方法中所有繼承自ValidateAttribute的特性,調用它們的Validate方法,例子中,只有一個NonNullValidate特性,它的Validate方法判斷了傳入的Value是否為空,如果未空就拋出異常。
????同樣,如果一個簡單的非空驗證不夠時,可能新寫一個特性類,繼承自ValidateAttribute,在需要的驗證的方法上添加這個特性就完成了。
????這么做的好處是什么?
????很簡單,代碼看起來清楚,修改更簡單。
????因為,不需要在代碼中可以避免很多 “if什么什么 throw什么什么”,代碼看起來就是,驗證什么變量,然后用這個變量什么什么干活。當大家不關心如何驗證時,就不會出現大段大段的驗證代碼,污染大家的視覺了,使要修改的代碼更容易找到。反過來,如果關心驗證,就看在這個方法上有些什么特性(當然特性的名字要取的好一點,弄個一串稀奇古怪的字符串,反而更看不懂),如果發現驗證用錯了,或者缺了什么驗證,修改一下方法上的特性就可以了。
????另一方面,這樣驗證代碼也可以重用起來,例如做了個英文大小寫的驗證特性,就可以直接在每一個需要這種驗證的方法上添加這個特性,而不需要每個方法自己實現。
????凡事總是有兩面的,說完優點,說說缺點,這個方式非常的靈活,但是代價是反射,在性能要求高于靈活要求的時候,這種方式就不適合了。

總結

以上是生活随笔為你收集整理的特性与方法注入的全部內容,希望文章能夠幫你解決所遇到的問題。

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