Yes, this is perfectly possible. All the built-in validators (such as equal/length etc) are built as custom property validators under the covers. Essentially, you just take parameters as constructor arguments for your custom validator. Here's a snippet from the FluentValidation code for Length:
This is the extension method that gives the syntax:
public static class Extensions {
public static IRuleBuilderOptions<T, string> Length<T>(this IRuleBuilder<T, string> ruleBuilder, int min, int max) {
return ruleBuilder.SetValidator(new LengthValidator(min, max));
}
}
...and the underlying validator:
public class LengthValidator : PropertyValidator, ILengthValidator {
public int Min { get; private set; }
public int Max { get; private set; }
public LengthValidator(int min, int max) : this(min, max, () => Messages.length_error) {
}
public LengthValidator(int min, int max, Expression<Func<string>> errorMessageResourceSelector) : base(errorMessageResourceSelector) {
Max = max;
Min = min;
if (max != -1 && max < min) {
throw new ArgumentOutOfRangeException("max", "Max should be larger than min.");
}
}
protected override bool IsValid(PropertyValidatorContext context) {
if (context.PropertyValue == null) return true;
int length = context.PropertyValue.ToString().Length;
if (length < Min || (length > Max && Max != -1)) {
context.MessageFormatter
.AppendArgument("MinLength", Min)
.AppendArgument("MaxLength", Max)
.AppendArgument("TotalLength", length);
return false;
}
return true;
}
}
...so essentially the custom arguments are passed to the custom validator through its constructor. If you'd like to see more examples, check out the implementation in the FV code:
https://github.com/JeremySkinner/FluentValidation/tree/master/src/FluentValidation/Validators
Jeremy