gpt4 book ai didi

c# - 如何组织 FluentValidation 规则以便它们可以在多个验证器中重用?

转载 作者:行者123 更新时间:2023-11-30 23:18:08 25 4
gpt4 key购买 nike

我有一个领域模型/实体,根据它的填充方式需要进行不同的验证。假设我提出了 3 个如下所示的验证器:

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.");
}
}

如何重构重复的 RuleFor(s),使它们只有一个并由不同的验证器共享?

谢谢,斯蒂芬

更新

我按照 Ouarzy 的想法运行,但是当我编写代码来验证它不会编译时。

[TestMethod]
public void CanChainRules()
{
var ticket = new Ticket();
ticket.Policy = new Policy();
ticket.Policy.ApplSignedInState = "CA";
ticket.Policy.PolicyNumber = "";
ticket.Policy.DistributionChannel = null;

var val = new Product1Validator();
var result = val.Validate(ticket); //There is no Method 'Validate'
Assert.IsTrue(!result.IsValid);
Console.WriteLine(result.Errors.GetValidationText());
}

更新 2

问题是新的复合验证器没有继承自 AbstractValidator,一旦我更正了它,它就可以编译,但它们似乎不起作用。

public class Product1Validator : AbstractValidator<Ticket>
{
public Product1Validator()
{
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();
}
}

最佳答案

集中式扩展方法

我想在多种不同类型的对象中使用它们。

我通过创建集中式扩展方法做到了这一点。

一个简单的例子:

扩展方法

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();
}
}

由于类型化对象是通过泛型传递的,因此它可以跨多个对象使用,而不仅仅是一个对象,即

public class UpdateCustomerValidator : AbstractValidator<UpdateCustomerCommand>

关于c# - 如何组织 FluentValidation 规则以便它们可以在多个验证器中重用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41023701/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com