2009-12-21 27 views
4

我有一個方法,只有在滿足某個條件時纔可以訪問,如果不是,那麼該方法將不會被執行。目前,這是我編寫的東西:現在使用屬性來檢查是否訪問方法

public void CanAccessDatabase() 
{ 
    if(StaticClass.IsEligible()) 
    { 
     return; 
    } 
    // do the logic 
} 

,這個代碼是醜陋的,因爲不出來哪裏有這個if(StaticClass.IsEligible())條件是不相關的方法的關注。

所以我正在考慮將IsEligible方法放在屬性中,以便我的代碼看起來像這樣。 如果條件未滿足,則此方法將僅返回而不執行下面的邏輯。

[IsEligibleCheck] 
public void CanAccessDatabase() 
{ 
    // do the logic 
} 

資格是一個運行時決定的,當然。

關於如何編碼IsEligibleCheck的邏輯的任何想法?謝謝

編輯:我知道PostSharp可以做到這一點,但我正在尋找一些可用的,不依賴任何第三方庫的東西。

+0

是一個資格編譯時或運行時決定呢? – 2009-12-21 01:27:18

+0

如果某些事情在無法訪問時嘗試調用該方法,會發生什麼情況?異常拋出?沉默失敗?垃圾結果? – 2009-12-21 01:27:30

+0

如果這是一個編譯時決定,那麼你可以使用屬性'[Conditional(「CONDITION1」)]' – 2009-12-21 01:39:08

回答

3

如何編寫了邏輯IsEligibleCheck任何想法?

這是AOP的絕佳去處。

編輯:我知道PostSharp可以做到這一點,但我正在尋找一些可以用於開箱即用的東西,而不依賴於任何第三方庫。

微軟認爲是第三方?如果沒有,你可以從他們的Patterns & Practices teamUnity。看看Unity中的Interceptor機制。

否則,您實際上必須使用反射來滾動自己的實現。有效地,你必須做的是將你的對象包裝在代理中,其中代理使用反射來檢查屬性並適當地解釋它們。如果IsEligibleCheck成功,則代理將調用包裝對象上的方法。真的,只重用一個已經存在的實現會更容易。

我的建議是使用Unity(或另一種AOP解決方案)。

+0

++用於提示統一性。由於公司要求,我懷疑OP不希望第三方的東西。該公司可能更適合使用MS產品。 – 2009-12-21 01:54:24

+2

我討厭打破新聞,但模式和實踐的東西不被視爲MS產品。他們可能建立在MS產品之上,由MS人員構建,但他們不受官方支持。 WCSF也是由P&P人員推出的,在這一點上它幾乎是一個廢棄的框架。 PostSharp和Castle很可能擁有比模式和實踐傢伙更多的社區支持。 – Josh 2009-12-21 02:28:25

2

這看起來很適合AOP。簡而言之,這意味着CanAccessDatabase邏輯將生活在一個「方面」或「攔截器」中,也就是與業務邏輯分開,因此實現了separation of concerns(該方面只負責安全性,業務代碼只負責爲商業事情)。

在C#中,用於執行AOP的兩個流行選項是Castle.DynamicProxyPostSharp。各有其優點和缺點。 This question總結他們的差異。

Here are other options用於在.Net中執行AOP,其中一些可以在沒有第三方庫的情況下完成。我仍然建議使用DynamicProxy,PostSharp,LinFu,Spring.AOP或Unity,其他解決方案几乎沒有靈活性。

+0

謝謝,因爲我可以使用PostSharp或Castle,我更喜歡一些.Net框架內置的,即不依賴於第三方庫。 – Graviton 2009-12-21 01:37:58

+0

@Ngu所有的Microsoft.Practices庫都是「第三方」正如先前在我的其他評論中所述,他們沒有得到官方的支持。 – Josh 2009-12-21 02:30:50

2

自定義屬性與Reflection結合在一起。

您將需要創建另一個類,負責調用CanAccessDatabase()類中的方法。

使用反射,這個新類將確定每個方法的屬性。如果找到IsEligibleCheck屬性,它將執行StatiClass.IsEligible()檢查,並且只有在檢查通過時才調用CanAccessDatabase()。

繼承人an introduction在MSDN上這樣做。它圍繞使用MemberInfo.GetCustomAttributes()方法進行。

繼承人的僞代碼:

Get the Type of the CanAccessDatabase() class 
Using this type, get all methods in this class (optionally filtering public, private etc). 
Loop through the list of methods 
    Call GetCustomAttributes() on the current method. 
    Loop through the list of custom attributes 
     If the IsEligibleCheck attribute is found 
      If StaticClass.IsEligible is true 
       Call the current method (using MethodInfo.Invoke()) 
      End If 
     End If 
    End Loop 
End Loop 
+0

謝謝,你有什麼例子嗎?到目前爲止,我得到的所有例子都沒有處理前提條件檢查。 – Graviton 2009-12-21 01:38:56

+0

我看過你的例子;它所說的就是如何在運行時檢查任何方法的屬性的存在並對其進行處理。但這意味着我必須專門編寫機制來檢查屬性,並在任何方法執行之前調用'Eligible'類。這就是我希望微軟已經寫好的那段代碼。我所要做的就是找出它。 – Graviton 2009-12-21 01:48:07

+0

@Ngu Soon Hui,是的,如果您自己選擇這樣做,您需要使用反射來首先檢查屬性,然後根據您的自定義邏輯執行該方法。如果你不想這樣做,你應該使用AOP製藥。微軟目前不提供AOP作爲框架C庫的一部分。 – Ash 2009-12-21 01:53:05

2

不幸的是,屬性沒有在運行時得到執行。一些內置屬性修改了編譯的代碼,如MethodImpl屬性和類似屬性,但所有自定義屬性都只是元數據。如果沒有代碼去尋找元數據,它就會坐在那裏,根本不會影響程序的執行。

換句話說,您需要if語句某處

除非您可以使用像PostSharp這樣的工具,否則您無法在開箱即用的.NET中完成此操作,而無需顯式檢查屬性。

0

檢查AOP,這將有助於你在這個有很多,在市場上強大的組成部分之一,是PostSharp

相關問題