A fluent interface builds configuration through chained method calls. Instead of placing rules in attributes or separate declarative metadata, you express related operations as a readable sequence. section 32.4.1
In .NET applications, fluent interfaces configure several kinds of behavior: EF Core entity mappings, options through an OptionsBuilder<T>, and validation rules in FluentValidation. Chaining keeps a rule close to the property or setting it modifies. section 12.6 section 31.4
Chaining validation rules
A validator can require a currency value, constrain its length, check an allowed-value list, and provide an error message in one chain: RuleFor(x => x.CurrencyTo) .NotEmpty() .Length(3) .MustBeCurrencyCode() .WithMessage("Not a valid currency code"); The chain can also use Must() for cross-property rules, such as rejecting a conversion whose source and destination currencies are identical. Reusable rules can be extracted into extension methods, while validators can receive dependencies through constructor injection. section 32.4.1
Listing 32.11 A FluentValidation validator for the currency converter binding model
public class CurrencyConverterModelValidator #1
: AbstractValidator<CurrencyConverterModel> #1
{
private readonly string[] _allowedValues #2
= new []{ "GBP", "USD", "CAD", "EUR" }; #2
public CurrencyConverterModelValidator() #3
{
RuleFor(x => x.CurrencyFrom) #4
.NotEmpty() #5
.Length(3) #5
.Must(value => _allowedValues.Contains(value)) #6
.WithMessage("Not a valid currency code"); #6
RuleFor(x => x.CurrencyTo)
.NotEmpty()
.Length(3)
.Must(value => _allowedValues.Contains(value))
.WithMessage("Not a valid currency code");
RuleFor(x => x.Quantity)
.NotNull()
.InclusiveBetween(1, 1000); #7
}
}
Shows a complete FluentValidation chain with property selection, built-in rules, a custom predicate, and an error message. section 32.4.1



