基本验证与业务验证,基本验证就是始终保持不变的验证规则,可以通过如下硬编码实现:

  1. public class Order
  2. {
  3. [Required]
  4. [Range(typeof(decimal), "", "")]
  5. public decimal Price { get; set; }
  6.  
  7. [Required]
  8. [StringLength()]
  9. public string Customer { get; set; }
  10.  
  11. [Required(AllowEmptyStrings=true)]
  12. [StringLength()]
  13. public string StoreID { get; set; }
  14. }

然后在用如下代码validate, 把错误放到List中:

  1. private bool ValidateBasicRule(Order order)
  2. {
  3. List<KeyValuePair<string, string>> errors = order.IsValid();
  4. if (errors.Count > )
  5. {
  6. this.AddRange(errors);
  7. return false;
  8. }
  9.  
  10. return true;
  11. }
  12.  
  13. public static class DataAnnotationHelper
  14. {
  15. public static List<KeyValuePair<string, string>> IsValid<T>(this T o)
  16. {
  17. List<KeyValuePair<string, string>> errors = new List<KeyValuePair<string, string>>();
  18.  
  19. var descriptor = GetTypeDescriptor(typeof(T));
  20.  
  21. foreach (PropertyDescriptor propertyDescriptor in descriptor.GetProperties())
  22. {
  23. foreach (var validationAttribute in propertyDescriptor.Attributes.OfType<ValidationAttribute>())
  24. {
  25. if (!validationAttribute.IsValid(propertyDescriptor.GetValue(o)))
  26. {
  27. errors.Add(new KeyValuePair<string, string>(propertyDescriptor.Name, validationAttribute.FormatErrorMessage(propertyDescriptor.Name)));
  28. }
  29. }
  30. }
  31. return errors;
  32. }
  33. private static ICustomTypeDescriptor GetTypeDescriptor(Type type)
  34. {
  35. return new AssociatedMetadataTypeTypeDescriptionProvider(type).GetTypeDescriptor(type);
  36. }
  37. }

然后说说业务规则的易变

SaaS程序,或者业务规则极其易变时,就要采用其他方法来做了,不可能每个公司都用设计模式分开写(虽然也行,但是不方便,公司业务规则多了后,对这些规则代码的管理就是很高的成本,而且要developer来负责)。所以要用规则文件来分开规则的编写,好处:

  1. 把修改的职责交给别人,比如项目经理、项目实施人员
  2. 代码不需要重新编译就能实现业务规则的修改

我们来解决下这个易变问题,假设有2公司:A和B。

A公司验证规则:

  1. 基本验证(就是Order类的验证规则的硬编码)
  2. 自定义验证规则:当前Order的下单网址必须来自于这几个url,如:www.cnblogs.com、www.cnblogs1.com、www.cnblogs2.com

B公司验证规则:

  1. 基本验证(同上)
  2. 自定义验证规则:无

如果用A2D规则引擎来解决的话,需要怎么做呢?

第一步当然是编写规则文件,A公司的规则文件:

  1. declare
  2. allowStores=["www.cnblogs.com", "www.cnblogs1.com", "www.cnblogs2.com"]
  3. end declare
  4. rule "test"
  5. when
  6. !_.contains(allowStores, entity.StoreID)
  7. then
  8. errors.Add("StoreID", "StoreID value not right")
  9. end rule

由于B公司没有自定义规则,因此不需要编写相应的规则文件

第二步,调整验证逻辑,如下:

  1. public class OrderService : BrokenRulesHolder
  2. {
  3. public int PlaceOrder(Order order)
  4. {
  5. this.ClearBrokenRules();
  6. //进行基本规则验证
  7. if (!ValidateBasicRule(order))
  8. return -;
  9.  
  10. //进行针对不同公司的规则验证
  11. if (!ValidateCompanyRule(order))
  12. return -;
  13.  
  14. //其他操作,比如插入数据库
  15.  
  16. return ;
  17. }
  18.  
  19. private bool ValidateCompanyRule(Order order)
  20. {
  21. BrokenRulesHolder tempBrokenRulesHolder = new BrokenRulesHolder();
  22. string rulePath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Rules", "OrderValidations", SessionContext.CompanyID + ".r");
  23. using (RuleEngine engine = new RuleEngine(false)) //false代表:如果规则文件不存在不会报错,而是忽略,默认为true
  24. {
  25. engine.BindRulePath(rulePath); //将规则文件的全路径传入引擎
  26.  
  27. engine.SetParameter("entity", order);
  28. engine.SetParameter("errors", tempBrokenRulesHolder);
  29.  
  30. engine.Process();
  31. }
  32. if (tempBrokenRulesHolder.BrokenRules.Count > )
  33. {
  34. this.AddRange(tempBrokenRulesHolder.BrokenRules);
  35. return false;
  36. }
  37. return true;
  38. }
  39.  
  40. private bool ValidateBasicRule(Order order)
  41. {
  42. List<KeyValuePair<string, string>> errors = order.IsValid();
  43. if (errors.Count > )
  44. {
  45. this.AddRange(errors);
  46. return false;
  47. }
  48.  
  49. return true;
  50. }
  51. }

BrokenRule.cs代码:

  1. public class BrokenRulesHolder
  2. {
  3. private List<KeyValuePair<string, string>> brokenRules = new List<KeyValuePair<string, string>>();
  4. public List<KeyValuePair<string, string>> BrokenRules
  5. {
  6. get
  7. {
  8. return this.brokenRules.AsReadOnly().ToList();
  9. }
  10. }
  11. public void Add(string key, string msg)
  12. {
  13. brokenRules.Add(new KeyValuePair<string, string>(key, msg));
  14. }
  15. public void AddRange(List<KeyValuePair<string, string>> rules)
  16. {
  17. brokenRules.AddRange(rules);
  18. }
  19. public void ClearBrokenRules()
  20. {
  21. brokenRules.Clear();
  22. }
  23. }

demo代码已经更新到A2D框架中了,这里就不upload运行图了。

A2D规则引擎已经内嵌了underscore1.5.2,因此规则定义文件(.r文件)中可以写相应的underscore函数来简化写法。

规则文件说明:

  1. declare
  2. allowStores1=["www.cnblogs.com", "www.cnblogs1.com", "www.cnblogs2.com"]
  3. allowStores2=["www.cnblogs.com", "www.cnblogs1.com", "www.cnblogs2.com"]
  4. end declare
  5. rule "rule 1"
  6. when
  7. !allowStores1.contains(entity.StoreID)
  8. then
  9. errors.Add("StoreID", "StoreID value not right")
  10. end rule
  11. rule "rule 2"
  12. when
  13. !allowStores2.contains(entity.StoreID)
  14. then
  15. errors.Add("StoreID", "StoreID value not right")
  16. end rule

declare section:

  1. 可以不写,但是最多只能存在1个这样的section
  2. 每行可以有逗号,也可以没有逗号
  3. 这个section的本意是:当前规则文件的变量全局定义、初始化工作
  4. 开头为declare,小写
  5. 结尾为end declare,小写

rule section:

  1. 必须存在1到多个
  2. 每行可以有逗号,也可以没有逗号
  3. 开头为rule "一些描述",小写
  4. 结尾为end rule,小写
  5. 如果存在3个rule时,最终会变成这样的js逻辑
    1. 加载underscorejs代码
    2.  
    3. 加载declare sectionjs代码
    4.  
    5. if(rule1 conditions)
    6. {
    7. 执行rule1then语句
    8. }
    9. else if(rule2 conditions)
    10. {
    11. 执行rule2then语句
    12. }
    13. else if(rule3 conditions)
    14. {
    15. 执行rule3then语句
    16. }

大家可以下载代码进行自己修改,比如可以插入自己编写的js代码来更加简化或者更加贴近项目的自定义方法、函数。

抽取非基本验证到规则文件 - A2D规则引擎的更多相关文章

  1. Drools 规则文件语法概述

    概述(Overview) 以.drl为扩展名的文件,是Drools中的规则文件,规则文件的编写,遵循Drools规则语法.下面详细介绍一下Drools规则文件语法.具体参考官方文档: https:// ...

  2. [原创]java WEB学习笔记71:Struts2 学习之路-- struts2常见的内建验证程序及注意点,短路验证,非字段验证,错误消息的重用

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  3. Struts2的输入校验(1)——校验规则文件的编写

    Struts2的输入校验(1) --校验规则文件的编写 Struts2提供了基于验证框架的输入校验,所有的输入校验只要编写配置文件,Struts2的验证框架将会负责进行服务器校验和客户端校验. 注: ...

  4. A2D规则引擎

    A2D规则引擎 写了个简单的规则引擎,普通情况够用了: 比如2家公司有各自的利率计算规则,如下: 在C#方面,没有写在C#的业务逻辑代码中,而是移到了外部规则文件中,如(ACompanyRatePol ...

  5. Struts(二十四):短路验证&重写实现转换验证失败时短路&非字段验证

    短路验证: 若对一个字段使用多个验证器,默认情况下会执行所有的验证.若希望前面的验证器没有通过,后面的验证器就不再执行,可以使用短路验证. 1.如下拦截器,如果输入字符串,提交表单后,默认是会出现三个 ...

  6. 如何在jenkins的maven项目中,用mvn命令行指定findbugs的黑名单规则文件

    一:问题背景 最近在研究jenkins的过程中,针对maven项目,打算添加findbugs进行静态检查,但我不太想在项目的pom中进行修改,最好可以只修改jenkins的job配置,即配置外部化. ...

  7. 极其好用好学的规则引擎 - A2D规则引擎

    写了个简单的规则引擎,普通情况够用了: 比如2家公司有各自的利率计算规则,如下: 在C#方面,没有写在C#的业务逻辑代码中,而是移到了外部规则文件中,如(ACompanyRatePolicy.r): ...

  8. AWVS11提取规则文件

    在这里给大家分享一个获取AWVS规则文件的思路.  目前我提取的是17年4月份的扫描规则.   后面如果规则更新,可以自行提取 官网:   https://www.acunetix.com/vulne ...

  9. .NET开源工作流RoadFlow-Bug修改-1.8.2表单验证时ueditor编辑非空验证无效

    RoadFlow生成的表单,Ueditor编辑器不能进行非空验证的BUG修改: 1.修改控制器:WorkFlowFormDesignerController红框处: 2.修改js文件:Scripts/ ...

随机推荐

  1. MFC更换画笔(画刷)颜色以及画眼睛(GDI画图)

    MFC画眼睛 换画笔(画刷)颜色(参考链接:https://blog.csdn.net/sunxiving/article/details/51272001) 由于画笔一旦创建后就无法修改.所以要修改 ...

  2. (其他)window10上好用的软件

    1.everything:比我用电脑搜索快一些,(常用的搜索其实熟悉电脑的都会,不过想快一点) 如果你曾对效率工具有过研究,想必对 Everything 的名字不会陌生.这款仅有 1.3 MB 的小软 ...

  3. LeetCode题解之Keys and Rooms

    1.题目描述 2.问题分析 使用深度优先遍历 3.代码 bool canVisitAllRooms(vector<vector<int>>& rooms) { int ...

  4. Linux 最小化安装后IP的配置(手动获取静态IP地址)

    一.图形化界面配置(假设为电脑A) 如果你的Linux安装有图形化界面,那么通过以下方式来配置: 我这里是有两块网卡,第一个网卡在上篇中已经通过DHCP来配置了:Linux 最小化安装后IP的配置(D ...

  5. 后台调用前端JS

    ClientScript.RegisterStartupScript(ClientScript.GetType(), "myscript", "<script> ...

  6. C#学习之接口

    什么是接口?其实,接口简单理解就是一种约定,使得实现接口的类或结构在形式上保持一致.个人觉得,使用接口可以使程序更加清晰和条理化,这就是接口的好处,但并不是所有的编程语言都支持接口,C#是支持接口的. ...

  7. CentOS 7.0安装

    CentOS 7.0安装 本次通过虚拟机的方法安装CentOS 7.0操作系统,开启虚拟机后会出现以下界面 1.选择第一项,Install CentOS 7 (安装CentOS 7),进入下面的界面 ...

  8. centos7如何安装gcc5.4

    由于需要使用到cilk plus和std=c++14,所以决定将编译器升级. 基本教程如下: 1.下载GCC源码: wget ftp://mirrors.kernel.org/gnu/gcc/gcc- ...

  9. 【转】10条你不可不知的css规则

    10条你不可不知的css规则 Posted on 2006-12-20 10:33 雨中太阳 阅读(343) 评论(1) 编辑 收藏 :[译]10条你不可不知的css规则正文: Published D ...

  10. 新近碰到的病毒(TR.Spy.Babonock.A)

    先来段Microsoft的说明: Worm:Win32/Babonock.A Alert level: Severe Detected with Windows Defender Antivirus ...