Is it possible to inject a condition (like a regex string, or integer) into a FluentValidation validator? That is, say I have multiple clients where each has different password requirements; can I inject that into the validator?
Something like:
public RegistrationValidator(int minLength, string regex)
{
RuleFor(registration => registration.Login).MinimumLength(minLength);
RuleFor(registration => registration.Password).Matches(regex);
}
If so, how exactly is it done? The closest I can figure is with root context data, but I feel like this should be simpler than that.
Yes, it's possible. you can inject any services you want from the constructor method in the validation class and create your custom validator. to define a rule like that you have 3 options.
1 - When / WhenAsync
2 - Must / MustAsync
3 - Custom / CustomAsync
For example, I want to inject my DbContext in the validator class, load the user and create a suitable validation for the current user.
User Class :
public class User
{
public int Id { get; set; }
public string PhoneNumber { get; set; }
public string PhoneNumberRegax { get; set; }
}
DTO class :
public class UserDto
{
public int Id { get; set; }
public string PhoneNumber { get; set; }
}
Validator Class
public class UserDtoValidator : AbstractValidator<UserDto>
{
private readonly UserDbContext _context;
public UserDtoValidator(UserDbContext context)
{
_context = context;
RuleFor(x => x).Must(CheckPhoneNumberRegax);
}
private bool CheckPhoneNumberRegax(UserDto inputUser)
{
var user = _context.Users.Single(o => o.Id = inputUser.Id);
var r = new Regex(user.PhoneNumberRegax, RegexOptions.IgnoreCase);
return r.IsMatch(inputUser.PhoneNumber);
}
}
Note: if use FluentValiation as ASP.NET Core Default validator must not use Async methods in the validator because ASP.NET Core validation pipeline is synchronous.