C# Fluentvalidation-将验证与特定流程最佳实践联系起来
将验证规则与特定流程联系起来的最佳实践是什么 目前,我正在使用“规则集”功能将规则分组到不同的流程:C# Fluentvalidation-将验证与特定流程最佳实践联系起来,c#,validation,c#-4.0,moq,fluentvalidation,C#,Validation,C# 4.0,Moq,Fluentvalidation,将验证规则与特定流程联系起来的最佳实践是什么 目前,我正在使用“规则集”功能将规则分组到不同的流程: public class ObjAValidation: AbstractValidator<A> { public ObjAValidation() { RuleSet("ProcessA", () => { RuleFor(x => ...);
public class ObjAValidation: AbstractValidator<A>
{
public ObjAValidation()
{
RuleSet("ProcessA", () =>
{
RuleFor(x => ...);
RuleFor(x => ...);
});
RuleSet("ProcessB", () =>
{
RuleFor(x => ...);
RuleFor(x => ...);
});
}
}
公共类ObjAValidation:AbstractValidator
{
公共对象化()
{
规则集(“ProcessA”,()=>
{
规则(x=>…);
规则(x=>…);
});
规则集(“ProcessB”,()=>
{
规则(x=>…);
规则(x=>…);
});
}
}
然后使用以下方法进行验证:
var a = new A(){...};
IValidator<A> validator = new ObjAValidation();
var result = validator.Validate(a, ruleSet: "ProcessA");
var a=new a(){…};
IValidator validator=新的ObjvaLidation();
var result=validator.Validate(a,规则集:“ProcessA”);
这种方法有两个问题:
Mock _mockValidator=new Mock();
_mockValidator.Setup(x=>x.Validate(新的A(),规则集:“ProcessA”);
第二行生成运行时错误:表达式树可能不包含命名参数规范。如果要在不使用命名参数的情况下传递规则集参数以验证方法,则必须提供“IValidatorSelector”对象。但是这个接口没有文档记录。是什么阻止您创建一个帮助器类,在这个类中您可以使用变量、数据结构或任何您喜欢的东西来阻止使用硬编码字符串参数?另外,不要忘记使用枚举的可能性
是什么阻止您创建一个实现IValidator的类,您也可以在其中实现您所需的自定义功能?我遇到了同样的问题,并找到了无法通过Moq etc
validator.Validate模拟此方法的原因(a,规则集:“ProcessA”)代码>是因为它是一个扩展方法,Moq不能模拟静态方法
有人在FluentValidation问题中提出了同样的问题:
简单的解决方案不是使用扩展方法,而是使用即时方法IValidator.validate(context)
。您所需要做的就是构建上下文。从这里查看源代码:
if(规则集!=null){
var ruleSetNames=ruleSet.Split(“,”,“;”).Select(x=>x.Trim());
选择器=ValidatorOptions.ValidatorSelectors.RulesetValidatorSelectorFactory(ruleSetNames.ToArray());
}
var context=new ValidationContext(实例,new PropertyChain(),选择器);
返回validator.Validate(上下文);
您考虑了EnLIB验证应用程序块吗?它还支持规则集。
Mock<IValidator<A>> _mockValidator = new Mock<IValidator<A>>();
_mockValidator.Setup(x => x.Validate(new A(), ruleSet: "ProcessA"));
if(ruleSet != null) {
var ruleSetNames = ruleSet.Split(',', ';').Select(x => x.Trim());
selector = ValidatorOptions.ValidatorSelectors.RulesetValidatorSelectorFactory(ruleSetNames.ToArray());
}
var context = new ValidationContext<T>(instance, new PropertyChain(), selector);
return validator.Validate(context);