FluentValidation について
C# で検証ロジックを扱うのに FluentValidation を利用させて頂いている。
EntityFramework の Fluent API のようにメソッドチェーン形式で検証ロジックを登録できるものである。
他の検証結果に依存した検証ロジック
他の項目の検証をパスした場合のみ実行したい検証ロジックというのは往々にしてあるものであるが、FluentValidation でも以下のようにサポートされている。
// 姓が入力されている場合に、名が入力されているか検証する。
RuleFor(x => x.Surname).NotNull().DependentRules(() => {
RuleFor(x => x.Forename).NotNull();
});
ただ、姓と名が入力されている場合に、ニックネームが入力されているか検証するといったように、複数の検証に依存したロジックは作者的にはあまり推奨していないようでサポートされていない。
しかしそれでは困るので拡張メソッドを用意することにした。
拡張メソッドの定義
デリゲートを受け取ったら検証クラスでラップし登録するような拡張メソッドを定義する。
AnonymouseValidator
public class AnonymouseValidator<T> : AbstractValidator<T>
{
public AnonymouseValidator(Action<AnonymouseValidator<T>> validator) => validator(this);
}
RuleBuilderExtensions
public static class RuleBuilderExtensions
{
public static IRuleBuilderOptions<T, TProperty> SetAnonymouseValidator<T, TProperty>(this IRuleBuilder<T, TProperty> ruleBuilder, Action<AbstractValidator<TProperty>> validator)
=> ruleBuilder.SetValidator(new AnonymouseValidator<TProperty>(validator));
}
使い方
SetAnonymouseValidator
で登録した検証をパスした場合に、DependentRules
が実行される。
RuleFor(_ => _)
.SetAnonymouseValidator(validator =>
{
validator.RuleFor(x => x.Surname).NotNull();
validator.RuleFor(x => x.Forename).NotNull();
})
.DependentRules(() =>
{
RuleFor(x => x.Nickname).NotNull();
});