using FluentValidation.Validators;
public static void Main()
private static void TestValidator(bool chain)
Console.WriteLine($"Testing validators (Chained validators: {chain})");
var validator = new MyObjectValidator(chain);
var instance = new MyObject();
var sourceVersion = new Version(1,0,0);
var targetVersion = new Version(2,0,0);
var result = validator.Validate(new ValidationContext<MyObject>(instance){
{ "TargetVersion", targetVersion},
{ "SourceVersion", sourceVersion }
Console.WriteLine($"\t[DEBUG]: instance.MyProperty = {instance.MyProperty}");
Console.WriteLine($"IsValid: {result.IsValid}");
public class MyObjectValidator : AbstractValidator<MyObject>
public MyObjectValidator(bool chainValidators){
RuleFor(instance => instance.MyProperty)
.SetValidator(new MyCustomValidator())
.SetValidator(new NotNullValidator2<MyObject, string>())
RuleFor(instance => instance.MyProperty)
.SetValidator(new MyCustomValidator());
RuleFor(instance => instance.MyProperty)
.SetValidator(new NotNullValidator2<MyObject, string>())
public class MyCustomValidator : PropertyValidator<MyObject, string>
public override string Name => "MyCustomValidator";
public override bool IsValid(ValidationContext<MyObject> context, string propertyValue) {
var version = context.RootContextData["SourceVersion"] as Version;
if(version < new Version(2,0,0) && string.IsNullOrWhiteSpace(propertyValue)){
Console.WriteLine("\t[DEBUG]: Setting value to 'Hello world'");
context.InstanceToValidate.MyProperty = "Hello world";
public class NotNullValidator2<T,TProperty> : PropertyValidator<T,TProperty>, INotNullValidator2 {
public override string Name => "NotNullValidator2";
public override bool IsValid(ValidationContext<T> context, TProperty value) {
Console.WriteLine($"\t[DEBUG] context.InstanceToValidate = {context.InstanceToValidate}, value = {value}");
protected override string GetDefaultMessageTemplate(string errorCode) {
return Localized(errorCode, Name);
public interface INotNullValidator2 : IPropertyValidator {
public string MyProperty {get;set;}
public override string ToString() => MyProperty;