如何使用NRules创建验证规则?

cru*_*zan 1 nrules

我刚刚发现了.NET的NRules。我想创建一个规则,以防止在字段/属性值无效时构造对象。例如,给定以下类:

public class Customer
{
    public string Name { get; private set; }
    public bool IsPreferred { get; set; }

    public Customer(string name)
    {
        Name = name;
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望创建一个规则,当“名称”为null或为空时,该规则将引发异常,从而取消对象创建以及生成用户定义的消息:必须指定客户名称。

可以使用NRules完成此操作吗?

Ser*_*yev 5

使用NRule,您可以根据特定域或对象模型编写规则。因此,您需要一些对象来保存数据,以便可以将这些对象插入规则会话中,也可以将这些对象与规则进行匹配。我想对于一个验证方案,您将使用以下之一:

  • 来自服务层的DTO
  • 表示层中的ViewModel对象
  • 调用其Build方法(即CustomerBuilder)之前的Builder对象
  • 域对象本身(对其进行构造,然后验证并在无效时丢弃)

在更高的层次上,NRules的优势在于可以通过稳定的域模型来表达易变的业务逻辑。在这种情况下,您可以将验证逻辑分为两组-1)稳定的验证,并定义域对象的固有不变性,即客户名称不为空;2)易变的验证逻辑(即,如果满足某些条件,则首选客户)。然后,您将在域模型本身中将类型1的验证逻辑编码为断言,并在这些域对象方面将类型2的验证逻辑编码为规则。

无论哪种方式,在机械级别上,您都可能希望验证规则为每个失败的验证插入一个ValidationError,然后在最后的查询会话中针对这些验证错误并防止对象构建(如果有)。

ObjectUnderValidation match = null;

When()
  .Match<ObjectUnderValidation>(() => match, x => x.ValidationCondition);

Then()
  .Do(ctx => ctx.Insert(new ValidationError(match, "Message")));
Run Code Online (Sandbox Code Playgroud)

稍后进行验证时:

var session = factory.CreateSession();
session.Insert(myObjectUnderValidation);

session.Fire();
var errors = session.Query<ValidationError>().ToList();

if (errors.Any())
  //Don't construct
else
  //Construct
Run Code Online (Sandbox Code Playgroud)

您还可以在此处抽象一些样板代码,以使其更易于在您的特定方案中使用。