C# 如何组织FluentValidation规则,以便它们可以在多个验证器中重用?
我有一个域模型/实体,根据它的填充方式,需要进行不同的验证。假设我提出了3个验证器,如下所示:C# 如何组织FluentValidation规则,以便它们可以在多个验证器中重用?,c#,fluentvalidation,C#,Fluentvalidation,我有一个域模型/实体,根据它的填充方式,需要进行不同的验证。假设我提出了3个验证器,如下所示: public class Product1Validator : AbstractValidator<Ticket> { public Product1Validator() { RuleFor(ticket => ticket.Policy.PolicyNumber) .NotEmpty() .WithMessag
public class Product1Validator : AbstractValidator<Ticket>
{
public Product1Validator()
{
RuleFor(ticket => ticket.Policy.PolicyNumber)
.NotEmpty()
.WithMessage("Policy Number is missing.");
RuleFor(ticket => ticket.Policy.ApplSignedInState)
.NotEmpty()
.WithMessage("Application Signed In State is missing or invalid.");
}
}
public class Product2Validator : AbstractValidator<Ticket>
{
public Product2Validator()
{
RuleFor(ticket => ticket.Policy.PolicyNumber)
.NotEmpty()
.WithMessage("Policy Number is missing.");
RuleFor(ticket => ticket.Policy.ApplSignedInState)
.NotEmpty()
.WithMessage("Application Signed In State is missing or invalid.");
}
}
public class Product3Validator : AbstractValidator<Ticket>
{
public Product3Validator()
{
RuleFor(ticket => ticket.Policy.PolicyNumber)
.NotEmpty()
.WithMessage("Policy Number is missing.");
RuleFor(ticket => ticket.Policy.ApplSignedInState)
.NotEmpty()
.WithMessage("Application Signed In State is missing or invalid.");
RuleFor(ticket => ticket.Policy.DistributionChannel)
.NotEmpty()
.WithMessage("Distribution Channel is missing.");
}
}
更新2
问题是新的复合验证器没有继承自AbstractValidator,一旦我纠正了这个问题,它就会编译,但它们似乎不起作用
public class Product1Validator : AbstractValidator<Ticket>
{
public Product1Validator()
{
TicketValidator.Validate().Policy().ApplSignedState();
}
}
公共类Product1Validator:AbstractValidator
{
公共产品1validator()
{
TicketValidator.Validate().Policy().ApplSignedState();
}
}
更新3
在对最初的答案大发雷霆并直接在GitHub上联系Jeremy后,我想到了以下几点:
class Program{
static void Main(string[] args){
var p = new Person();
var pv = new PersonValidator();
var vr = pv.Validate(p);
//Console.ReadKey();
}
}
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime BirthDate { get; set; }
}
class PersonValidator : AbstractValidator<Person>
{
public PersonValidator()
{
CascadeMode = CascadeMode.Continue;
this.FirstName();
this.LastName();
}
}
static class Extensions
{
public static void FirstName(this AbstractValidator<Person> a)
{
a.RuleFor(b => b.FirstName).NotEmpty();
}
public static void LastName(this AbstractValidator<Person> a)
{
a.RuleFor(b => b.LastName).NotEmpty();
}
}
类程序{
静态void Main(字符串[]参数){
var p=新人();
var pv=新的PersonValidator();
var vr=pv.Validate(p);
//Console.ReadKey();
}
}
班主任
{
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共日期时间出生日期{get;set;}
}
类PersonValidator:AbstractValidator
{
公共PersonValidator()
{
级联模式=级联模式。继续;
this.FirstName();
this.LastName();
}
}
静态类扩展
{
公共静态void FirstName(此抽象验证器a)
{
a、 RuleFor(b=>b.FirstName).NotEmpty();
}
公共静态void LastName(此抽象验证器a)
{
a、 RuleFor(b=>b.LastName).NotEmpty();
}
}
在您的情况下,我可能会尝试使用所有规则为票据建立一个流畅的验证,然后调用每个产品所需的验证。比如:
public class TicketValidator : AbstractValidator<Ticket>
{
public TicketValidator Policy()
{
RuleFor(ticket => ticket.Policy.PolicyNumber)
.NotEmpty()
.WithMessage("Policy Number is missing.");
return this;
}
public TicketValidator ApplSignedState()
{
RuleFor(ticket => ticket.Policy.ApplSignedInState)
.NotEmpty()
.WithMessage("Application Signed In State is missing or invalid.");
return this;
}
public TicketValidator DistributionChannel()
{
RuleFor(ticket => ticket.Policy.DistributionChannel)
.NotEmpty()
.WithMessage("Distribution Channel is missing.");
return this;
}
public static TicketValidator Validate()
{
return new TicketValidator();
}
}
我没有试图编译这段代码,但我希望你能看到这个想法
希望有帮助。集中扩展方法方法 我想跨多种不同类型的对象使用它们 我通过创建集中的扩展方法实现了这一点 一个简单的例子: 扩展方法
namespace FluentValidation
{
public static class LengthValidator
{
public static IRuleBuilderOptions<T, string>
CustomerIdLength<T>(this IRuleBuilder<T, string> ruleBuilder)
{
return ruleBuilder.Length<T>(1, 0);
}
}
}
名称空间FluentValidation
{
公共静态类长度验证器
{
公共静态IRuleBuilderOptions
CustomerIdLength(此IRuleBuilder规则生成器)
{
返回ruleBuilder.Length(1,0);
}
}
}
用法
public class CreateCustomerValidator : AbstractValidator<CreateCustomerCommand>
{
public CreateCustomerValidator()
{
RuleFor(x => x.CustomerId).CustomerIdLength();
}
}
公共类CreateCustomerValidator:AbstractValidator
{
public CreateCustomerValidator()
{
(x=>x.CustomerId).CustomerIdLength()的规则;
}
}
当类型化对象通过泛型传递时,它可以跨多个对象使用,而不仅仅是一个对象
公共类UpdateCustomerValidator:AbstractValidator
原样编译的代码很好,谢谢。但是当我编写代码调用它时,它不会编译。正如您在我的代码中看到的,验证函数必须由您编写,在我的示例中,它只是一个返回空验证器的工厂方法。如果你愿意,可以叫它Empty()或Build()或Create(),对不起,我有点笨。你是说要修改“publicstaticticketvalidator validator()”,我不太明白你的意思。我确实喜欢链子的样子,但我不能让它工作。
namespace FluentValidation
{
public static class LengthValidator
{
public static IRuleBuilderOptions<T, string>
CustomerIdLength<T>(this IRuleBuilder<T, string> ruleBuilder)
{
return ruleBuilder.Length<T>(1, 0);
}
}
}
public class CreateCustomerValidator : AbstractValidator<CreateCustomerCommand>
{
public CreateCustomerValidator()
{
RuleFor(x => x.CustomerId).CustomerIdLength();
}
}