void IValidationRuleInternal <T> .AddDependentRules(IEnumerable <IValidationRuleInternal <T> > rules)
 {
     if (DependentRules == null)
     {
         DependentRules = new();
     }
     DependentRules.AddRange(rules);
 }
Beispiel #2
0
        /// <summary>
        /// Triggers an action when the rule passes. Typically used to configure dependent rules. This applies to all preceding rules in the chain.
        /// </summary>
        /// <param name="rule">The current rule</param>
        /// <param name="action">An action to be invoked if the rule is valid</param>
        /// <returns></returns>
        public static IRuleBuilderOptions <T, TProperty> DependentRules <T, TProperty>(this IRuleBuilderOptions <T, TProperty> rule, Action <DependentRules <T> > action)
        {
            var dependencyContainer = new DependentRules <T>();

            action(dependencyContainer);
            rule.Configure(cfg => {
                cfg.DependentRules.AddRange(dependencyContainer);
            });
            return(rule);
        }
Beispiel #3
0
        /// <summary>
        /// Triggers an action when the rule passes. Typically used to configure dependent rules. This applies to all preceding rules in the chain.
        /// </summary>
        /// <param name="rule">The current rule</param>
        /// <param name="action">An action to be invoked if the rule is valid</param>
        /// <returns></returns>
        public static IRuleBuilderOptions <T, TProperty> DependentRules <T, TProperty>(this IRuleBuilderOptions <T, TProperty> rule, Action <DependentRules <T> > action)
        {
            var dependencyContainer = new DependentRules <T>();

            if (rule is IExposesParentValidator <T> exposesParentValidator)
            {
                if (exposesParentValidator.ParentValidator is AbstractValidator <T> parent)
                {
                    // Capture any rules added to the parent validator inside this delegate.
                    void OnRuleAddedToParent(IValidationRule r)
                    {
                        dependencyContainer.AddRule(r);
                        parent.NestedValidators.Remove(r);
                    }

                    using (parent.NestedValidators.OnItemAdded(OnRuleAddedToParent)) {
                        action(dependencyContainer);
                    }
                }
            }
            else
            {
                action(dependencyContainer);
            }


            rule.Configure(cfg => {
                if (!string.IsNullOrEmpty(cfg.RuleSet))
                {
                    foreach (var dependentRule in dependencyContainer)
                    {
                        var propRule = dependentRule as PropertyRule;
                        if (propRule != null && string.IsNullOrEmpty(propRule.RuleSet))
                        {
                            propRule.RuleSet = cfg.RuleSet;
                        }
                    }
                }

                cfg.DependentRules.AddRange(dependencyContainer);
            });
            return(rule);
        }
Beispiel #4
0
        /// <summary>
        /// Applies the condition to the rule asynchronously
        /// </summary>
        /// <param name="predicate"></param>
        /// <param name="applyConditionTo"></param>
        public void ApplyAsyncCondition(Func <ValidationContext, CancellationToken, Task <bool> > predicate, ApplyConditionTo applyConditionTo = ApplyConditionTo.AllValidators)
        {
            // Default behaviour for When/Unless as of v1.3 is to apply the condition to all previous validators in the chain.
            if (applyConditionTo == ApplyConditionTo.AllValidators)
            {
                foreach (var validator in Validators.ToList())
                {
                    var wrappedValidator = new DelegatingValidator(predicate, validator);
                    ReplaceValidator(validator, wrappedValidator);
                }

                foreach (var dependentRule in DependentRules.ToList())
                {
                    dependentRule.ApplyAsyncCondition(predicate, applyConditionTo);
                }
            }
            else
            {
                var wrappedValidator = new DelegatingValidator(predicate, CurrentValidator);
                ReplaceValidator(CurrentValidator, wrappedValidator);
            }
        }
        /// <summary>
        /// Triggers an action when the rule passes. Typically used to configure dependent rules. This applies to all preceding rules in the chain.
        /// </summary>
        /// <param name="rule">The current rule</param>
        /// <param name="action">An action to be invoked if the rule is valid</param>
        /// <returns></returns>
        public static IRuleBuilderOptions <T, TProperty> DependentRules <T, TProperty>(this IRuleBuilderOptions <T, TProperty> rule, Action <DependentRules <T> > action)
        {
            var dependencyContainer = new DependentRules <T>();

            action(dependencyContainer);

            rule.Configure(cfg => {
                if (!string.IsNullOrEmpty(cfg.RuleSet))
                {
                    foreach (var dependentRule in dependencyContainer)
                    {
                        var propRule = dependentRule as PropertyRule;
                        if (propRule != null && string.IsNullOrEmpty(propRule.RuleSet))
                        {
                            propRule.RuleSet = cfg.RuleSet;
                        }
                    }
                }

                cfg.DependentRules.AddRange(dependencyContainer);
            });
            return(rule);
        }
Beispiel #6
0
        private Task RunDependentRulesAsync(List <ValidationFailure> failures, ValidationContext context, CancellationToken cancellation)
        {
            var validations = DependentRules.Select(v => v.ValidateAsync(context, cancellation).Then(fs => failures.AddRange(fs), runSynchronously: true));

            return(TaskHelpers.Iterate(validations, cancellationToken: cancellation));
        }