好久沒寫文章了,主要是前面一段時間比較忙,一直沒空學習和思考,好不容易找了個休息日,寫一下blog
前幾篇已經寫到過特性,並且用它實現了一些東西。這次來談一下一種比較怪異的特性的運用——方法注入。
其實,說他怪異,稍微過了點,因為就連m$給大家的類庫就用這種運用,舉個例子transactionattribute,就是乙個對事務相關方法的乙個行為指導的注入。為什麼這麼說,transactionattribute可以定義強制開始乙個新的事務或者使用已經存在的事務,或者定義事務的隔離級別。但是,特性本身什麼事情也不能做,必須由別的類來讀去這個特性,由別的類根據這個特性做某些事,transactionattribute為什麼會起作用?原因是在事務處理時,處理函式會建立乙個stacktrace,通過查詢當前堆疊上的方法的transactionattribute,獲得相關的事務資訊,通過這些,事務處理函式就以期望的方式工作了。(因為特性標記在某個直接或間接呼叫到事務的方法上,所以執行事務的時候,這個方法一定在這個堆疊上)
利用這個原理,可以做出一種類似的,利用特性注入方法的方式。這裡就以最簡單的驗證引數為例:
1、建立乙個驗證特性,作為所有驗證特性的基類:
public
abstract
class
validateattribute : attribute
public
abstract
void
validate(
object
value);}
2、建立乙個過濾空引用的驗證特性:
[attributeusage(attributetargets.method, allowmultiple
=false
, inherited
=false
)]public
sealed
class
nonnullvalidateattribute
: validateattribute
public
override
void
validate(
object
value)}
public
static
class
validator}}
4、用起來看看吧
static
object
_testfield;
static
void
main(
string
args)
catch
(exception ex)
console.readline();
}static
object
testprop
[nonnullvalidate()]
set}
跑起來看看,看到了什麼?對了argumentnullexception的預設message,
validator.validate並沒有任何顯式的丟擲這個異常,那麼為什麼會檢測出這個空引數哪?
原因在於validator.validate檢查了當前呼叫堆疊中前乙個方法(當前方法就是validator.validate自身),也就是呼叫validator.validate方法的方法,讀去這個方法中所有繼承自validateattribute的特性,呼叫它們的validate方法,例子中,只有乙個nonnullvalidate特性,它的validate方法判斷了傳入的value是否為空,如果未空就丟擲異常。
同樣,如果乙個簡單的非空驗證不夠時,可能新寫乙個特性類,繼承自validateattribute,在需要的驗證的方法上新增這個特性就完成了。
這麼做的好處是什麼?
很簡單,**看起來清楚,修改更簡單。
因為,不需要在**中可以避免很多 「if什麼什麼 throw什麼什麼」,**看起來就是,驗證什麼變數,然後用這個變數什麼什麼幹活。當大家不關心如何驗證時,就不會出現大段大段的驗證**,汙染大家的視覺了,使要修改的**更容易找到。反過來,如果關心驗證,就看在這個方法上有些什麼特性(當然特性的名字要取的好一點,弄個一串稀奇古怪的字串,反而更看不懂),如果發現驗證用錯了,或者缺了什麼驗證,修改一下方法上的特性就可以了。
另一方面,這樣驗證**也可以重用起來,例如做了個英文大小寫的驗證特性,就可以直接在每乙個需要這種驗證的方法上新增這個特性,而不需要每個方法自己實現。
凡事總是有兩面的,說完優點,說說缺點,這個方式非常的靈活,但是代價是反射,在效能要求高於靈活要求的時候,這種方式就不適合了。
SQL 注入與防範方法
前言 所謂sql注入,就是通過把sql命令插入到web表單遞交或輸入網域名稱或頁面請求的查詢字串,最終達到欺騙伺服器執行惡意的sql命令。首先要有乙個思想觀念 1.以下例項中,輸入的使用者名稱必須為字母 數字及下劃線的組合,且使用者名稱長度為 8 到 20 個字元之間 if preg match w...
spring 方法注入 lookup方法注入
1 無狀態bean 與有狀態bean 無狀態bean bean一旦例項化就被加進會話池中,各個使用者都可以共用。即使使用者已經消亡,bean 的生命期也不一定結束,它可能依然存在於會話池中,供其他使用者呼叫。有狀態bean 有狀態會話bean 每個使用者有自己特有的乙個例項,在使用者的生存期內,be...
spring方法注入 Spring方法注入
spring方法注入 spring核心現成可用,有兩個作用域 單例和原型。單例實現單例模式,這意味著在執行時 在jvm中 只有乙個例項。spring在上下文建立期間例項化它們,將它們快取在上下文中,並在需要時 或類似的東西 從快取中提供它們。每次訪問上下文以獲取bean時都會例項化原型。當需要在單例...