C# 使用自定义规则的动态验证

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个字符-为什么我要重建整个项目(或业务类项目) 我想如果我有一个有我的自定义规则的文件,那么当需要更改时,我可以简单地在其中放置一个新规则。我在互联网上读过一些文章,这些

我已经使用.Net语言4年了。我使用WCF开发3层和5层应用程序,ASP.NET用于web应用程序,C#用于windows应用程序。每次我启动一个项目时,都会关注业务规则和验证

我应该在哪里放置自定义验证规则(按钮单击事件、页面加载或类中的setters/getter)

如果一个项目很大,并且只有一个字段,而不是5个字符应该是7个字符-为什么我要重建整个项目(或业务类项目)

我想如果我有一个有我的自定义规则的文件,那么当需要更改时,我可以简单地在其中放置一个新规则。我在互联网上读过一些文章,这些文章为此提供了基于XML的文件,但这似乎有问题,因为:

  • 没有Intellisense,XML文件中的错误很难找到
  • 我们必须编写自定义XML解析器
  • 因为这种方法需要大量的强制转换,所以速度非常慢
我的问题:

是否存在使用.NET方法(反射、表达式树、Lambda表达式、动力学、DLL的运行时创建等)的设计模式或其他任何东西,以使用自定义规则进行动态验证


编辑1)


属性呢?我们可以将它们与反射一起用于自定义验证吗?我们可以用这种方法根据另一个属性(表单示例P1应该是P2+1)验证属性吗?

表示业务规则的最佳方法是xml。为了充分利用这种表示法,您应该首先定义规则引擎数据模型的结构,即回答以下问题

  • 规则是什么
  • 规则可以分类吗
  • 规则是否包含公共属性(属性),如允许的值、格式等
  • 完成后,创建一个虚拟规则xml,然后基于该xml派生一个xml模式。该工具可以帮助您创建模式。如果可以使用以下工具,那么创建模式会更容易

    至于你具体问题的答案

    • 我们不能使用Intellisense,如果XML文件中有错误,很难找到它
    一旦您有了模式,VisualStudio就在创建xml(包括intellisense和验证)方面提供了充分的支持

    • 我们应该编写一个自定义xml解析器
    不需要,提供序列化/反序列化逻辑,即将规则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);