2013-05-21 55 views
4

我希望你們能給我一些好的建議。我正在考慮如何爲C#開發構建一個好的架構。我盡我所能解釋的情況,因爲我不是在英語好:需要一個好的體系結構來驗證規則

1)兩大類:藍色銀行和紅色銀行

2)第三類:遊戲規則驗證

3)藍和紅銀行有幾個字段(值),如賬戶號碼,金額,InvoicePeriod等等......這裏的例子(XML):

Blue銀行

<AccountNumber>Maria 5987593457</AccountNumber> 
    <Amount>200.00</Amount> 
    <InvoicePeriod>1</InvoicePeriod> 

紅色銀行

<AccountNumber>8529458</AccountNumber> 
    <Amount>300.00</Amount> 
    <InvoicePeriod>0</InvoicePeriod> 

紅/藍銀行有一些相同的驗證規則,如金額字段,必須是數字。但紅藍銀行有不同的驗證規則 - 在Blue Bank中AccountNumber字段必須是字母數字,而在Red Bank中AccountNumber必須是Numberic否則將失敗。 InvoicePeriod字段在Red Bank中必須默認爲1,而在Blue Bank中必須爲默認值0,否則將失敗。

我的想法是:

我要創建的每個類紅色/藍色銀行進行驗證不同的規則,然後我還可以創建驗證類的爲藍/紅銀行具有相同的規則的規則。

我的代碼在這裏:

Blue銀行類:

  • 驗證賬戶號碼必須是alphanumberic否則失敗
  • 驗證InvoicePeriod必須是默認爲1,否則失敗

紅色銀行類:

  • 驗證賬戶號碼必須是數字小否則失敗
  • 驗證InvoicePeriod必須是默認爲0,否則失敗

RulesOfValidation類

  • 驗證金額這必須是數字的(紅/藍銀行類別的規則相同)

它是如何與字典<,>與這些類一起工作的?或者使用示例代碼提供更好的建議?

您的幫助將不勝感激。

+0

對於驗證,您可以查看['IDataErrorInfo'](http://msdn.microsoft.com/zh-cn/library/system.componentmodel.idataerrorinfo.aspx)接口,請參閱示例[here]( http://www.asp.net/ mvc/tutorials/older-versions/models-%28data%29/validating-with-the-idataerrorinfo-interface-cs) – polkduran

回答

0

您應該使用System.ComponentModel.DataAnnotations

首先創建抽象類銀行

abstract class Bank 
{ 
    #region fields 
    private List<string> errorMessages = new List<string>(); 
    #endregion 

    #region publioc methods 
    public virtual void Validate() 
    { 
     ValidateRulesAtributes(); 
    } 

    #endregion 

    #region helper methods 
    private void ValidateRulesAtributes() 
    { 
     var validationContext = new ValidationContext(this, null, null); //ValidationContext -> Reference System.ComponentModel.DataAnnotations 
     var result = new List<ValidationResult>(); 
     Validator.TryValidateObject(this, validationContext, result, true); 



     result.ForEach(p => { errorMessages.Add(p.ErrorMessage); }); 

     if (errorMessages.Any()) 
      throw new Exception(errorMessages.Aggregate((m1, m2) => String.Concat(m1, Environment.NewLine, m2))); 
    } 

    protected void Validate(List<string> messages) 
    { 
     if (errorMessages == null) 
      errorMessages = new List<string>(); 

     if (messages != null) 
      messages.ForEach(p => { errorMessages.Add(p); }); 
     ValidateRulesAtributes(); 

    } 
    #endregion 
    #region properties 
    //Abstract to indicate Validation atributes 

    public abstract string AccountNumber { get; set; } 

    public abstract double Amount { get; set; } 
    public abstract int InvoicePeriod { get; set; } 
    #endregion 

} 

第二,數據anotations

class BlueBank : Bank 
    { 
     //All is ok, no validate 
     public override string AccountNumber { get; set; } 

     public override double Amount { get; set; } 

     public override int InvoicePeriod { get; set; } 

    } 
class RedBank : Bank 
    { 
     [Required()] 
     public override string AccountNumber { get; set; } 

     public override double Amount { get; set; } 
     [Range(0,0)] 
     public override int InvoicePeriod { get; set; } 


     public override void Validate() 
     { 
      List<string> errors=new List<string>(); 
      if (AccountNumber != "Test") 
       errors.Add("Worng Account"); 
      base.Validate(errors); 
     } 

    } 

使用Atributes驗證範圍,要求等創建紅色和藍色銀行.. 覆蓋驗證()到複雜的驗證

這是一個簡單的例子

class Program 
    { 
     static void Main(string[] args) 
     { 
      RedBank red = new RedBank(); 
      red.AccountNumber = "Test"; 

      red.Amount=0; 
      red.Validate(); //this No fail 

      red.InvoicePeriod = 3; //This Fail; 
      red.Validate(); 

      red.AccountNumber = "PD"; 
      red.Validate(); //this fal: 

     } 
    } 
1

我會用IRule接口與Validate()方法,它可以在具體驗證類中實現,該驗證類可以包含驗證邏輯。然後,您將能夠在銀行中執行多個自定義規則。將IRule類型對象的列表傳遞給銀行類,並在每個傳遞銀行參數上運行Validate()。所以每家銀行都可以根據通過的規則進行驗證。

interface IRule 
{ 
    bool Validate(Bank someBank); 
} 

abstract class Bank 
{ 
    public string AccountNumber; 
    public string Amount; 
    public string InvoicePeriod; 

    private List<IRule> listOfRules = new List<IRule>(); 

    public void ValidateAllRules(){ 
     foreach (var ite in listOfRules){ 
      ite.Validate(this); 
      //if validation will not pass then I don't know what you want to do ;) 
     } 
    } 

    public void AddRule(IRule rule) 
    { 
     listOfRules.Add(rule); 
    } 
} 

class RedBank : Bank 
{ 
    public RedBank(){ 
     listOfRules.Add(new SimpleRule()); 
     listOfRules.Add(new SimpleRule2()); 
    } 
} 

class SimpleRule : IRule 
{ 
    public bool Validate(Bank someBank) 
    { 
     return someBank.AccountNumber.Contains("567"); 
    } 
} 

class SimpleRule2 : IRule 
{ 
    public bool Validate(Bank someBank) 
    { 
     return someBank.Amount.Contains(".") && someBank.InvoicePeriod.Contains("-"); 
    } 
} 
+0

我喜歡你的建議。也許你可以在這裏給我一個很好的例子代碼,這樣我就能在腦海中看到一幅清晰的圖畫。如果你不介意的話:-) – user1358072

+0

就像這樣,看起來有點像giacomelli發佈的規範模式。 – Mateusz

+0

非常感謝你! – user1358072

相關問題