4

希望大家能给我一些好的建议。我正在考虑如何为 C# 开发创建一个好的架构。我正在尽力解释场景,因为我不擅长英语:

1)两个班:蓝银行和红银行

2)第三类:验证规则

3) 蓝色和红色银行有几个字段(值),例如 AccountNumber、Amount、InvoicePeriod 等......这里的示例(xml):

蓝色银行

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

红银行

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

红/蓝银行有一些相同的验证规则,例如必须是数字的金额字段。但是红/蓝银行有不同的验证规则——蓝银行中的帐号字段必须是字母数字,而红银行中的帐号必须是数字,否则会失败。InvoicePeriod 字段在 Red Bank 中必须默认为 1,而在 Blue Bank 中必须默认为 0,否则失败。

我的想法是:

我想为不同的验证规则创建每个红色/蓝色银行类,然后我还为蓝色/红色银行拥有的相同规则创建一个验证类规则。

我的代码在这里:

蓝色银行类:

  • 验证必须是字母数字的 AccountNumber 否则失败
  • 验证必须为默认值 1 的 InvoicePeriod 否则失败

红银行类:

  • 验证必须为数字的 AccountNumber 否则失败
  • 验证必须为默认值 0 的 InvoicePeriod 否则失败

RulesOfValidation 类

  • 验证必须为数字的金额(Red / Blue Bank 类的规则相同)

它如何与这些类的字典 <,> 一起使用?或者您的示例代码有什么更好的建议?

您的帮助将不胜感激。

4

3 回答 3

5

规范模式是解决您问题的好选择。您可以为常见的银行规则创建规范类,并为每个特定需求创建其他规范类。

这种模式有一些 c# 库:

于 2013-05-21T14:10:39.267 回答
3

我会使用可以在包含验证逻辑的具体验证类中实现的方法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("-");
    }
}
于 2013-05-21T14:04:43.217 回答
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);
        }

    }

使用属性来验证范围、要求等。覆盖 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:

        }
    }
于 2013-05-21T14:35:19.813 回答