コード例 #1
0
        /// <summary>
        /// Determines whether or not a rule should execute.
        /// </summary>
        /// <param name="rule">The rule</param>
        /// <param name="propertyPath">Property path (eg Customer.Address.Line1)</param>
        /// <param name="context">Contextual information</param>
        /// <returns>Whether or not the validator can execute.</returns>
        public bool CanExecute(IValidationRule rule, string propertyPath, IValidationContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (propertyPath == null)
            {
                throw new ArgumentNullException(nameof(propertyPath));
            }

            var dependencies = context.GetDependencies(propertyPath);

            if (rule != null)
            {
                dependencies = dependencies.Concat(rule.GetDependencies(context));
            }

            if (HasIndexers)
            {
                propertyPath = IndexerMatcher.Value.Replace(propertyPath, "[]");
                dependencies = dependencies.Select(propertyPath => IndexerMatcher.Value.Replace(propertyPath, "[]"));
            }

            // Validator selector only applies to the top level.
            // If we're running in a child context then this means that the child validator has already been selected
            // Because of this, we assume that the rule should continue (i.e. if the parent rule is valid, all children are valid)
            var isChildContext = context.IsChildContext;
            var cascadeEnabled = !context.RootContextData.ContainsKey(DisableCascadeKey);

            return(isChildContext && cascadeEnabled && !PropertyPaths.Any(x => x.Contains('.')) ||
                   rule is IIncludeRule ||
                   Matches(propertyPath) ||
                   dependencies.Any(Matches));

            bool Matches(string otherPath) => PropertyPaths.Any(path => path == otherPath ||
                                                                IsSubPath(otherPath, path) ||
                                                                IsSubPath(path, otherPath));
        }