2011-08-16 38 views
4

我一直使用.Net語言4年。我開發了使用WCF的3層和5層應用程序,用於Web應用程序的ASP.NET和用於Windows應用程序的C#。每次我開始一個項目時,業務規則和驗證都是一個問題。使用自定義規則進行動態驗證

我應該在哪裏放置自定義驗證規則(按鈕單擊事件,頁面加載或在我的類中的setter/getters)?

如果一個項目很大,並且只有一個字段而不是5個字符應該是7個字符 - 爲什麼我應該重建整個項目(或業務類項目)?

我想如果我有一個文件,有我的自定義規則,那麼當需要更改時,我可以簡單地放入一個新規則。我已閱讀,提供用於此目的的基於XML的文件在互聯網上的一些文章,但是這似乎有問題,因爲:

  • 沒有智能感知和XML文件中的錯誤是很難找到
  • 我們必須寫自定義XML解析器
  • 由於這種方法需要大量的石膏,這是非常緩慢的

我的問題:

是否有設計模式或其他使用.NET方法(反射,表達式樹,Lambda表達式,動態,DLL的運行時創建等)使用自定義規則進行動態驗證的設計模式?


編輯1)

什麼屬性?我們可以使用它們反射到自定義驗證嗎?我們可以用這種方法驗證另一個屬性的財產(形式示例P1應該是P2 + 1)嗎?

+0

[屬性](http://msdn.microsoft.com/en-us/library/system.attribute.aspx)爲類提供某種元數據,等等。您可以在'property1'上定義一個自定義屬性'以便它可以與同一個實例的'property2'鏈接。但是這種方法很複雜,導致依賴規則的硬編碼。 –

回答

5

表示業務規則的最佳方式是使用xml。要充分利用這種符號,您應該先定義規則引擎數據模型的結構,即回答這些問題。

  1. 什麼是規則?
  2. 規則可以分類嗎?
  3. 規則是否包含允許的值,格式等常用屬性(屬性)?

完成此操作後,創建一個虛擬規則xml,然後根據此xml導出xml模式。 xsd.exe工具可以幫助您創建模式。如果您可以使用諸如Altova XmlSpy之類的工具,則創建該模式會更容易。

至於回答您的具體問題,

  • 我們不能使用智能感知,如果我們在XML文件中的錯誤是很難發現它。

一旦你有了到位的架構時,Visual Studio提供了創建XML(包括智能感知和驗證)的充分支持。

  • 我們應該編寫自定義XML解析器

不是必需的,XmlSerializer Class用於序列化/反序列化即提供了一種邏輯規則XML轉換爲規則的數據模型,並且反之亦然。

  • 由於這種方法需要大量的鑄造,這是非常緩慢的

那麼,這是相比於硬編碼規則(規則嵌入到你的組件類的局部有效點),但這種方法的靈活性遠遠超過了任何性能缺點。如果規則發生變化,則不需要重新構建解決方案。在大多數情況下,性能影響很小。

除非您有嚴格的性能標準,否則xml方法是實現規則引擎的首選方式。請記住,架構越鬆散,運行時的靈活性越高,但對性能有負面影響。

樣品規則

<RulesEngine> 
    <Rules> 
    <Rule Id="Rule1"> 
     <Function> 
     <Equals> 
      <Property name="Property1" classId="MyClassId"/> 
      <Sum> 
       <Property name="Property2" classId="MyClassId"/> 
       <Constant type="UInt16" value="1"/> 
      </Sum> 
      </Equals> 
     </Function> 
     </Rule> 
    </Rules> 
    <Classes> 
    <Class name="MyNamespace.MyClass" Id="MyClassId"> 
     <Property name="Property1" type="UInt16"/> 
     <Property name="Property2" type="UInt16"/> 
    </Class> 
    </Classes> 
</RulesEngine> 

規則引擎需要解釋這一規則,並相應地推斷意義。

+0

謝謝,如果你想比較XML和動態代dll和類,你的想法是什麼? – Arian

+0

考慮如果我想要一個定製的規則,根據該屬性shpuld是屬性2 + 1.什麼是用XML實現這樣的規則的首選方式? – Arian

+0

xml規則方法確實從xml動態創建規則數據模型。但我不能評論動態生成方法,因爲我沒有使用它,但它可能會使用[CodeDOM](http://msdn.microsoft.com/en-us/library/y2k85ax6.aspx) –

4

看看FluentValidation。它使用表達式,並且您可以創建條件驗證(例如,如果一個符合某些標準,則驗證這些屬性)。 FV可能不是動態的,但你會獲得智能感知,表現力和類型安全性。它的通用性意味着它運行得相當快。您可以通過傳入驗證代理或自定義驗證器來注入一些運行時動態,這些驗證代碼可以做任何您能想到的事情。

這意味着你必須重新編譯,但你可以把驗證器放在一個單獨的程序集中。並且驗證者而不是在課堂上/課堂上是有意義的,因爲您經常發現驗證在上下文中執行。例如,如果汽車的所有車輪都有可能是有效的。但是,如果你試圖駕駛它並且沒有汽油,那麼駕駛就「無效」。這就是說,我將找到規則「接近」他們正在驗證的內容,因爲它們是您網域的一部分。

+0

謝謝'FluentValidation'是非常有趣的驗證框架。請參閱編輯1 – Arian

+1

當然。 FV使用命令式代碼(例如'RuleFor(...)。Must(...)')以基本上創建關於什麼是有效的聲明性語句;它可以設置依賴關係,就像你使用屬性的想法一樣。我贊成前一種方法,因爲依賴性更簡潔明瞭(1行代碼與遍佈整個類型的屬性進行驗證)。這也可以讓你有條件地創建依賴。 – Kit

+0

thanks.can FV在兩個屬性之間創建依賴規則?這樣的P1 = P2 + 1是否在它的文檔中解釋了它? – Arian