C# 使用自定义规则的动态验证
我已经使用.Net语言4年了。我使用WCF开发3层和5层应用程序,ASP.NET用于web应用程序,C#用于windows应用程序。每次我启动一个项目时,都会关注业务规则和验证 我应该在哪里放置自定义验证规则(按钮单击事件、页面加载或类中的setters/getter) 如果一个项目很大,并且只有一个字段,而不是5个字符应该是7个字符-为什么我要重建整个项目(或业务类项目) 我想如果我有一个有我的自定义规则的文件,那么当需要更改时,我可以简单地在其中放置一个新规则。我在互联网上读过一些文章,这些文章为此提供了基于XML的文件,但这似乎有问题,因为:C# 使用自定义规则的动态验证,c#,.net,design-patterns,c#-4.0,business-rules,C#,.net,Design Patterns,C# 4.0,Business Rules,我已经使用.Net语言4年了。我使用WCF开发3层和5层应用程序,ASP.NET用于web应用程序,C#用于windows应用程序。每次我启动一个项目时,都会关注业务规则和验证 我应该在哪里放置自定义验证规则(按钮单击事件、页面加载或类中的setters/getter) 如果一个项目很大,并且只有一个字段,而不是5个字符应该是7个字符-为什么我要重建整个项目(或业务类项目) 我想如果我有一个有我的自定义规则的文件,那么当需要更改时,我可以简单地在其中放置一个新规则。我在互联网上读过一些文章,这些
- 没有Intellisense,XML文件中的错误很难找到
- 我们必须编写自定义XML解析器
- 因为这种方法需要大量的强制转换,所以速度非常慢
编辑1)
属性呢?我们可以将它们与反射一起用于自定义验证吗?我们可以用这种方法根据另一个属性(表单示例P1应该是P2+1)验证属性吗?表示业务规则的最佳方法是xml。为了充分利用这种表示法,您应该首先定义规则引擎数据模型的结构,即回答以下问题
- 我们不能使用Intellisense,如果XML文件中有错误,很难找到它
- 我们应该编写一个自定义xml解析器
- 因为这种方法需要大量的浇铸,所以速度很慢
规则引擎需要解释此规则并相应地推断其含义。请查看。它使用表达式,您可以创建条件验证(例如,如果满足某些条件,则验证这些属性)。FV可能没有开箱即用的那么动态,但您可以获得智能感、表达能力和类型安全性。它的通用性意味着它运行得相当快。您可以通过传递验证委托或自定义验证器来注入一些运行时动态,这些验证委托或自定义验证器可以执行您所能想到的任何操作
这确实意味着您必须重新编译,但您可以将验证器放在单独的程序集中。验证程序不在类中是有意义的,因为您经常发现验证是在上下文中执行的。例如,如果一辆车有所有的轮子,它可能是有效的。但是,如果你试图驾驶它,但它没有汽油电池,那么它的驾驶“无效”。也就是说,我会将规则定位为“接近”它们正在验证的内容,因为它们是您域的一部分
如果需要依赖于一个或多个属性(包括其本身)的属性的规则,如果不满足该规则的条件,则需要自定义消息,可以对执行此操作。考虑这一点:
RuleFor(x => x.P1)
.Must(x => x.P1 > x.P2)
.Message("P1 must be one more than P2. P1 was {0}; P2 was {1}", x=>x.P1, x=>x.P2);
提供了一个简单的比较,但您可以做得更复杂。谢谢,如果您想比较XML和动态生成DLL和类,你的想法是什么?考虑一下,如果我想要一个定制的规则,根据Primt1 Spuld是Prime2+1,用XML实现这类规则的首选方法是什么?XML规则方法确实从XML动态创建规则数据模型。但是我不能评论动态生成方法,因为我没有使用它,但它可能使用是的,该方法类似于,只是符号不同。如果您熟悉它们,您可以使用它们。我没有表达式树的第一手经验,但您可以参考MSDN()或。最好还是在上的表达式树上查找问题。谢谢
FluentValidation
是一个非常有趣的验证框架。请参阅编辑1部分。FV以流畅的风格使用命令式代码(例如,RuleFor(…)。Must(…)
)来创建关于什么是有效的声明性语句;它可以像使用属性一样设置依赖项。不过,我支持前一种方法,因为依赖关系的指定更加简洁(1行代码与分布在整个被验证类型中的属性相比)。这也允许您调节它
RuleFor(x => x.P1)
.Must(x => x.P1 > x.P2)
.Message("P1 must be one more than P2. P1 was {0}; P2 was {1}", x=>x.P1, x=>x.P2);