我希望你们能给我一些好的建议。我在想如何为C#开发建立一个好的架构。我正在尽力解释情景,因为我不擅长英语:
1)两个班级:Blue Bank和Red Bank
2)第三课:验证规则
3)蓝色和红色银行有几个字段(值),如AccountNumber,Amount,InvoicePeriod等......示例(xml):
Blue Bank
<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字段在Red Bank中必须为默认值1,而在Blue Bank中必须为默认值0,否则将失败。
我的想法是:
我想为不同的验证规则创建每个Red / Blue Bank类,然后我还为Blue / Red银行的相同规则创建验证类规则。
我的代码在这里:
蓝银班:
红银班:
RulesOfValidation类
如何使用dictonary&lt;,&gt;这些课程?或者您的示例代码有什么更好的建议吗?
我们非常感谢您的帮助。
答案 0 :(得分:5)
Specification Pattern是您的问题的一个很好的选择。您可以为每个特定需求创建公共银行规则和其他规范类的规范类。
此模式有一些c#库:
答案 1 :(得分: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("-");
}
}
答案 2 :(得分: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验证范围,必需等。 将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:
}
}