FluentValidation を使用してオブジェクト内のコレクションを検証し、コレクション項目の要素を親オブジェクトの要素と比較しています。
目標の出力は、コレクションを失敗させるだけでなく、コレクション内の失敗したアイテムごとに ValidationFailures を受け取ることです。
ソフトウェア項目のリストを含むソフトウェアの注文があります。注文がレガシー システムの場合、選択されたソフトウェアはレガシー ソフトウェアのみであり、逆の場合、非レガシー システムは非レガシー ソフトウェアのみを持つことができます。
私のモデル:
public class SoftwareOrder
{
public bool IsLegacySystem;
public List<SoftwareItem> Software;
(...other fields...)
}
public class SoftwareItem
{
public bool Selected;
public bool IsLegacySoftware;
public int SoftwareId;
}
バリデーター:
public class SoftwareOrderValidator : AbstractValidator<SoftwareOrder>
{
public SoftwareOrderValidator()
{
(..other rules..)
When(order => order.IsLegacySystem == true, () =>
{
RuleForEach(order => order.SoftwareItem)
.SetValidator(new SoftwareItemValidator(true));
});
When(order => order.IsLegacySystem == false, () =>
{
RuleForEach(order => order.SoftwareItem)
.SetValidator(new SoftwareItemValidator(false));
});
}
}
public class SoftwareItemValidator : AbstractValidator<SoftwareItem>
{
public SoftwareItemValidator(bool IsLegacySystem)
{
When(item => item.Selected, () =>
{
RuleFor(item => item.IsLegacySoftware)
.Equal(IsLegacySystem).WithMessage("Software is incompatible with system");
});
}
}
ご覧のとおり、条件ごとに When を設定することでこれを実現しています。機能しますが、DRY に違反しており、条件が 2 つ以上ある状況で使用するのは実用的ではありません。
理想的には、これを実行できる単一の RuleForEach が必要です。When は必要ありません。次のようなものです。
RuleForEach(order => order.SoftwareItem)
.SetValidator(new SoftwareItemValidator(order => order.IsLegacySystem));
しかし、IsLegacySystem をそのコンストラクターに渡す方法がわかりません。