特性與方法注入

2021-09-05 17:51:07 字數 2219 閱讀 6184

好久沒寫文章了,主要是前面一段時間比較忙,一直沒空學習和思考,好不容易找了個休息日,寫一下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時都會例項化原型。當需要在單例...