我有三个实体如下,它们相互链接如下:
class Class1
{
int id { get; set; }
Class2 { get; set; }
}
class Class2
{
int id { get; set; }
Class3 { get; set; }
}
class Class3
{
int id { get; set; }
Class1 { get; set; }
}
现在我为每个类创建了验证器,并为链接到它们的实体提供了SetValidator
:
//Class1 (and other classes) validator has following rules:
public class Class1Validator()
{
public Class1Validator()
{
RuleFor(x => x.id).NotEqual(0).WithMessage("id is required.");
RuleFor(x => x.Class2).SetValidator(new Class2Validator());
}
}
public class Class2Validator()
{
public Class2Validator()
{
RuleFor(x => x.id).NotEqual(0).WithMessage("id is required.");
RuleFor(x => x.Class3).SetValidator(new Class3Validator());
}
}
public class Class3Validator()
{
public Class3Validator()
{
RuleFor(x => x.id).NotEqual(0).WithMessage("id is required.");
RuleFor(x => x.Class1).SetValidator(new Class1Validator());
}
}
//Now when following is called:
var validator = new Class1Validator();
当我检查Class1
的验证时,它还包含Class2
的验证程序,然后Class2
包含Class3
,最后也包含Class3
有Class1
的验证器,它形成一个无限循环并抛出以下错误:
mscorlib.dll中出现未处理的“System.StackOverflowException”类型异常
并且在查看完整详细信息时显示:
无法计算表达式,因为当前线程处于堆栈溢出状态。
任何解决方案或我在这里做错了吗?
更新: 我也尝试过以下我可以限制验证器,如果object为null,但这不起作用:
When(x => x.Class1 != null, () => RuleFor(x => x.Class1).SetValidator(new Class1Validator()));
答案 0 :(得分:0)
我找到了打破循环引用的方法:
SetValidator
个调用移出构造函数,转换为Initialize()
方法。SetValidator()
次调用中重用验证程序实例。例如,将验证程序实例存储为静态类中的静态字段。好吧,我的言语不太好,所以这里是代码:
用于验证验证器实例并在其上调用Initialize()
的类:
public static class Validators
{
public static Class1Validator Class1Validator = new Class1Validator();
public static Class2Validator Class2Validator = new Class2Validator();
public static Class3Validator Class3Validator = new Class3Validator();
static Validators()
{
Class1Validator.Initialize();
Class2Validator.Initialize();
Class3Validator.Initialize();
}
}
验证器现在变为:
public class Class1Validator : AbstractValidator<Class1>
{
public Class1Validator()
{
RuleFor(x => x.id).NotEqual(0).WithMessage("id is required.");
}
public void Initialize()
{
RuleFor(x => x.Class2).SetValidator(Validators.Class2Validator);
}
}
public class Class2Validator : AbstractValidator<Class2>
{
public Class2Validator()
{
RuleFor(x => x.id).NotEqual(0).WithMessage("id is required.");
}
public void Initialize()
{
RuleFor(x => x.Class3).SetValidator(Validators.Class3Validator);
}
}
public class Class3Validator : AbstractValidator<Class3>
{
public Class3Validator()
{
RuleFor(x => x.id).NotEqual(0).WithMessage("id is required.");
}
public void Initialize()
{
RuleFor(x => x.Class1).SetValidator(Validators.Class1Validator);
}
}
我测试了这个,似乎工作正常。例如:
var validator = Validators.Class1Validator;
var c1 = new Class1
{
id = 1,
Class2 = new Class2
{
id = 2,
Class3 = new Class3
{
id = 3,
Class1 = new Class1
{
id = 0,
Class2 = null
}
}
}
};
var result = validator.Validate(c1);
此处 result
为false,因为内部Class1
实例的Id
为0
。
我担心这种方法的线程安全性,但显然可以,如here所述:
验证器只能实例化一次 - 它们是线程安全的。