ドメイン オブジェクトであるデータソースをカプセル化する ViewModel があります。ドメインには、ドメインで定義されている検証ルールがありますが、ユーザーに情報を提供するために ViewModel によって再利用されます。
ビューモデル:
internal class RatedValuesViewModel : FluentDataErrorInfo
{
public RatedValuesViewModel()
: base(new RatedValuesViewModelValidator())
{
}
public RatedValues DataSource { get; set; }
...
}
ドメイン オブジェクト:
class RatedValues
{
public double? Head
{
get; set;
}
public double? DeltaPressure
{
get; set;
}
...
}
これから実行する操作のコンテキストにおけるドメイン オブジェクト ルールは次のとおりです。
class GeneratePlotPumpCurvesRatedValuesValidationRules : AbstractValidator<RatedValues>
{
public GeneratePlotPumpCurvesRatedValuesValidationRules()
{
Custom(itemToValidate => !AtLeastOneParameterSpecified(itemToValidate) ? new ValidationFailure(string.Empty, "You must specify at least one rated value.") : null);
RuleFor(item => item.Head).Must(head => head == null).When(item => item.DeltaPressure != null).WithMessage("You can not specify both head and delta pressure.");
RuleFor(item => item.DeltaPressure).Must(dp => dp == null).When(item => item.Head != null).WithMessage("You can not specify both head and delta pressure.");
}
...
}
最後に: ドメイン内の検証ルールを再利用するビュー モデルの検証ルール:
class RatedValuesViewModelValidator : AbstractValidator<RatedValuesViewModel>
{
private readonly GeneratePlotPumpCurvesRatedValuesValidationRules _generatePlotPumpCurvesRatedValuesValidationRules = new GeneratePlotPumpCurvesRatedValuesValidationRules();
public RatedValuesViewModelValidator()
{
RuleFor(viewModel => viewModel.DataSource).SetValidator(_generatePlotPumpCurvesRatedValuesValidationRules);
Custom(viewModel =>
{
if (viewModel.DataSource == null)
return null;
ValidationResult validationResult = _generatePlotPumpCurvesRatedValuesValidationRules.Validate(viewModel.DataSource, viewModel.DataSource.GetPropertyName(vm => vm.Head));
return !validationResult.IsValid ? new ValidationFailure(viewModel.GetPropertyName(vm => vm.Head), CombineErrors(validationResult.Errors)) : null;
} );
}
private static string CombineErrors(IEnumerable<ValidationFailure> errors)
{
StringBuilder combinedErrors = new StringBuilder();
errors.ForEach(error => combinedErrors.AppendLine(error.ErrorMessage));
return combinedErrors.ToString();
}
}
ビューモデルの検証クラスでは、プロパティ「ヘッド」に定義された検証ルールを再利用し、それらをビューモデル プロパティ「ヘッド」のルールとして公開します。ご覧のとおり、私が頻繁に行うことになるコードには、非常に多くのコードがあります。流暢な検証フレームワーク機能を使用して、この「検証プロパティ プロジェクション」を設定できますか?