我一直在审查FluentValidation
这是一个很好的验证库,但我注意到它们传递LambdaExpression
而不是对象属性,我想了解这种用法的优点:
using FluentValidation;
public class CustomerValidator: AbstractValidator<Customer> {
public CustomerValidator() {
RuleFor(customer => customer.Surname).NotEmpty();
RuleFor(customer => customer.Forename).NotEmpty().WithMessage("Please specify a first name");
RuleFor(customer => customer.Company).NotNull();
RuleFor(customer => customer.Discount).NotEqual(0).When(customer => customer.HasDiscount);
RuleFor(customer => customer.Address).Length(20, 250);
RuleFor(customer => customer.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");
}
private bool BeAValidPostcode(string postcode) {
// custom postcode validating logic goes here
}
}
Customer customer = new Customer();
CustomerValidator validator = new CustomerValidator();
ValidationResult results = validator.Validate(customer);
bool validationSucceeded = results.IsValid;
IList<ValidationFailure> failures = results.Errors;
正如您所看到的那样RuleFor(customer => customer.Surname).NotEmpty();
,RuleFor(customer.Surname).NotEmpty();
还不够干净?
答案 0 :(得分:6)
相反,
RuleFor(customer.Surname).NotEmpty();
不够干净?
没有。因为在您致电RuleFor
时,您没有客户 - 因此您无法访问他们的姓氏。
与代理人通常的情况一样,你传递代码以便稍后执行。表达式customer.Surname
是一个表达式,它将在现有customer
变量的上下文中立即进行评估。
现在,如果我们拥有神秘的infoof运算符,我们可以执行此操作而无需创建委托。我们可以写一些类似的东西:
RuleFor(infoof(Customer.Surname)).NotEmpty()
哪个会很可爱。 RuleFor
方法将采用该属性引用,并在以后针对给定客户对其进行评估。精彩。
不幸的是,我们没有那个运营商 - 所以表达“当你有一个客户,获得Surname
财产”的想法的最简单方法是使用代表。它也非常灵活,因为它可以(几乎)使用你想要执行的任何代码。
答案 1 :(得分:1)
如果您要传递customer.SurName
,则会指向特定SurName
实例的customer
属性的值。使用lambda函数允许验证逻辑在调用验证逻辑时获取客户对象,然后检索 客户的SurName
属性。