2013-05-21 5 views
4

Надеюсь, вы, ребята, можете дать мне хорошие предложения. Я думаю, как создать хорошую архитектуру для разработки C#. Я стараюсь изо всех сил, чтобы объяснить сценарии, потому что им не хорошо на английском:Нужна хорошая архитектура для правил валидации

1) Два класса: Синий банк и Red Bank

2) Третий класс: Правила Validations

3) синий и красный Банки имеют несколько полеев (значения), такие как ACCOUNTNUMBER, сумма, InvoicePeriod и т.д. ... Пример здесь (XML):

Синего банк

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

Red Bank

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

Красные/синие банки имеют одни и те же правила валидации, такие как суммы полей, которые должны быть численными. Но у Red/Blue Banks есть разные правила валидации - поле AccountNumber должно быть буквенно-числовым в Blue Bank, тогда как AccountNumber должно быть числовым в Red Bank иначе не удалось. Поле InvoicePeriod должно быть по умолчанию 1 в Red Bank, тогда как оно должно быть по умолчанию 0 в Blue Bank иначе не выполнено.

Моя идея:

Я хочу создать каждый класс красной/синюю банку для различных правил проверки, а затем я также создать правила класса валидации для одних и тех же правил, что синие/красные банки имеют.

Мой код здесь:

Синий Bank класс:

  • Validate AccountNumber, который должен быть alphanumberic иначе не удалось
  • Validate InvoicePeriod, который должен быть по умолчанию 1 в противном случае не удалось

Red Bank класс:

  • Validate AccountNumber, который должен быть Numberic иначе не удалось
  • Validate InvoicePeriod, который должен быть по умолчанию 0 в противном случае не удалось

RulesOfValidation класс

  • Validate Сумма которые должны быть числовыми (одинаковые правила для классов Red/Blue Bank)

Как это работает с диктатором <,> с этими классами? Или любое лучшее предложение с примерами кодов?

Ваша помощь будет высоко оценена.

+0

Для проверки вы можете ознакомиться с интерфейсом ['IDataErrorInfo' (http://msdn.microsoft.com/en-us/library/system.componentmodel.idataerrorinfo.aspx), см. Пример [здесь] (http://www.asp.net/ mvc/tutorials/old-versions/models-% 28data% 29/validating-with-the-idataerrorinfo-interface-cs) – polkduran

ответ

0

Вы должны использовать System.ComponentModel.DataAnnotations

сначала создать абстрактный класс Bank

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 

} 

Второй Создать красный и синий банка с данными

разъяснения
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 для проверки диапазонов, требуется, и т.д .. Override Validate() для сложных валидаций

Это простой пример

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

Мне нравится предложение ur. Может быть, вы можете дать мне хорошие примеры здесь, чтобы я мог видеть ясную картину в своем уме. Если вы не возражаете :-) – user1358072

+0

Что-то вроде этого, немного похоже на шаблон спецификации, который опубликовал giacomelli. – Mateusz

+0

Большое спасибо !!!! – user1358072

5

Specification Pattern является хорошим вариантом для вашей проблемы. Вы можете создать класс спецификации для общих банковских правил и других классов спецификации для каждой конкретной потребности.

Существует несколько C# библиотеки для этой модели:

+0

не знал, что шаблоны, его довольно сладкие –

Смежные вопросы