使用 NRules,您可以根据特定的域或对象模型编写规则。因此,您需要一些对象来保存数据,以便您可以将这些对象插入到规则会话中,并且还可以将这些对象与规则匹配。我想对于验证场景,您将使用以下方法之一:
- 来自服务层的 DTO
- 表示层的 ViewModel 对象
- 调用其 Build 方法之前的 Builder 对象(即 CustomerBuilder)
- 域对象本身(构造它,然后验证并丢弃如果无效)
在更高的层次上,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")));
稍后进行验证时:
var session = factory.CreateSession();
session.Insert(myObjectUnderValidation);
session.Fire();
var errors = session.Query<ValidationError>().ToList();
if (errors.Any())
//Don't construct
else
//Construct
您还可以在此处抽象一些样板代码,使其更易于在您的特定场景中使用。