public StartPreservationCommandValidator( IProjectValidator projectValidator, ITagValidator tagValidator) { CascadeMode = CascadeMode.Stop; RuleFor(command => command.TagIds) .Must(ids => ids != null && ids.Any()) .WithMessage("At least 1 tag must be given!") .Must(BeUniqueTags) .WithMessage("Tags must be unique!") .MustAsync(BeInSameProjectAsync) .WithMessage("Tags must be in same project!") .MustAsync(NotBeAClosedProjectForTagAsync) .WithMessage("Project is closed!"); When(command => command.TagIds.Any() && BeUniqueTags(command.TagIds), () => { RuleForEach(command => command.TagIds) .MustAsync((_, tagId, __, token) => BeAnExistingTagAsync(tagId, token)) .WithMessage((_, id) => $"Tag doesn't exist! Tag={id}") .MustAsync((_, tagId, __, token) => NotBeAVoidedTagAsync(tagId, token)) .WithMessage((_, id) => $"Tag is voided! Tag={id}") .MustAsync((_, tagId, __, token) => IsReadyToBeStartedAsync(tagId, token)) .WithMessage((_, id) => $"Preservation on tag can not be started! Tag={id}") .MustAsync((_, tagId, __, token) => HaveAtLeastOneNonVoidedRequirementAsync(tagId, token)) .WithMessage((_, id) => $"Tag do not have any non voided requirement! Tag={id}"); }); bool BeUniqueTags(IEnumerable <int> tagIds) { var ids = tagIds.ToList(); return(ids.Distinct().Count() == ids.Count); } async Task <bool> BeInSameProjectAsync(IEnumerable <int> tagIds, CancellationToken token) => await projectValidator.AllTagsInSameProjectAsync(tagIds, token); async Task <bool> NotBeAClosedProjectForTagAsync(IEnumerable <int> tagIds, CancellationToken token) => !await projectValidator.IsClosedForTagAsync(tagIds.First(), token); async Task <bool> BeAnExistingTagAsync(int tagId, CancellationToken token) => await tagValidator.ExistsAsync(tagId, token); async Task <bool> NotBeAVoidedTagAsync(int tagId, CancellationToken token) => !await tagValidator.IsVoidedAsync(tagId, token); async Task <bool> IsReadyToBeStartedAsync(int tagId, CancellationToken token) => await tagValidator.IsReadyToBeStartedAsync(tagId, token); async Task <bool> HaveAtLeastOneNonVoidedRequirementAsync(int tagId, CancellationToken token) => await tagValidator.HasANonVoidedRequirementAsync(tagId, token); }