예제 #1
0
        /// <summary>
        /// If no existing instance is passed in, creates a new instance of the type T and populates its matching property values with each <see cref="Validatable{T}"/> object in the group of <see cref="Validatables"/>.
        /// </summary>
        /// <typeparam name="T">The type of the class to be instantiated and populated.</typeparam>
        /// <param name="validatableGroup">The group of <see cref="Validatable{T}"/> objects whose Values to use to populate the class instance.</param>
        /// <param name="model">Optionally pass in an existing class instance to update.</param>
        /// <returns>Class of type T with the property values set based on the <see cref="Validatables"/>.</returns>
        public static T Populate <T>(this Validatables validatableGroup, T model = null)
            where T : class, new()
        {
            var instance        = model ?? new T();
            var instanceType    = instance.GetType();
            var validatableType = typeof(Validatable <>);

            foreach (var obj in validatableGroup.Objects)
            {
                var prop = instanceType.GetProperty(obj.ClassPropertyName);
                if (prop == null)
                {
                    continue;
                }

                var validatable = validatableType.MakeGenericType(prop.PropertyType);
                var valProp     = validatable.GetProperty("Value");

                if (valProp != null)
                {
                    prop.SetValue(instance, valProp.GetValue(obj), null);
                }
            }

            return(instance);
        }
예제 #2
0
        /// <summary>
        /// Takes a validation result and splits it into individual results for each <see cref="Validatable{T}"/> object.
        /// </summary>
        /// <param name="valResult">The original Fluent <see cref="ValidationResult"/> from a class instance comprised of the values of the individual <see cref="Validatable{T}"/> object properties.</param>
        /// <param name="validatableGroup">The <see cref="Validatable{T}"/> object properties to apply results to.</param>
        /// <returns>An <see cref="OverallValidationResult"/> summarizing the original results (on the entire instance) as well as any rule results that were not captured by the <see cref="Validatable{T}"/> objects.</returns>
        public static OverallValidationResult ApplyResultsTo(this ValidationResult valResult, Validatables validatableGroup)
        {
            var overallResult = new OverallValidationResult
            {
                IsValidOverall = valResult.IsValid,
                AllErrors      = valResult.Errors.Select(e => e.ErrorMessage).ToList()
            };

            validatableGroup.AreValid = true;

            foreach (var obj in validatableGroup.Objects)
            {
                obj.IsValid = true;

                var relevantFailures = valResult.Errors
                                       .Where(e => e.PropertyName == obj.ClassPropertyName).ToList();

                if (!relevantFailures.Any())
                {
                    continue;
                }

                var errors = relevantFailures.Select(e => e.ErrorMessage).ToList();
                obj.Errors  = errors;
                obj.IsValid = false;

                validatableGroup.Errors.AddRange(errors);

                relevantFailures.ForEach(failure => valResult.Errors.Remove(failure));
            }

            if (validatableGroup.Errors.Any())
            {
                validatableGroup.AreValid = false;
            }

            overallResult.NonSplitErrors           = valResult.Errors.Select(e => e.ErrorMessage).ToList();
            overallResult.IsValidForNonSplitErrors = overallResult.NonSplitErrors.Count == 0;

            return(overallResult);
        }
예제 #3
0
        /// <summary>
        /// Returns the ValidationRule objects from an <see cref="AbstractValidator{T}"/> that are relevant to the given <see cref="Validatable{T}"/> objects.
        /// </summary>
        /// <typeparam name="T">The Type of the class that the <see cref="Validatable{T}"/>object properties pertains to, and therefore is the target Type for the <see cref="AbstractValidator{T}"/>.</typeparam>
        /// <param name="validator">The Fluent <see cref="AbstractValidator{T}"/> instance.</param>
        /// <param name="validatableGroup">The <see cref="Validatable{T}"/> objects for which to retrieve ValidationRules for.</param>
        /// <returns>A List of IValidationRule relevant to the <see cref="Validatable{T}"/> objects.</returns>
        public static List <IValidationRule> GetRulesFor <T>(this AbstractValidator <T> validator, Validatables validatableGroup)
        {
            var descriptor = validator.CreateDescriptor();

            var rules = new List <IValidationRule>();

            foreach (var obj in validatableGroup.Objects)
            {
                rules.AddRange(descriptor.GetRulesForMember(obj.ClassPropertyName));
            }

            return(rules);
        }