Пример #1
0
        //

        /// <summary>
        /// Creates a new <see cref="ModelMappingDictionary"/> for an object model type.
        /// </summary>
        /// <param name="modelType">The type of object model to read property mappings from.</param>
        /// <returns>A new, filled instance.</returns>
        public static ModelMappingDictionary CreateFrom(Type modelType)
        {
            if (modelType == null)
            {
                throw new ArgumentNullException(nameof(modelType));
            }

            var modelMappingDictionary = new ModelMappingDictionary(modelType);

            foreach (var mapping in GetModelMappingsForPropertiesOfType(modelType))
            {
                modelMappingDictionary.Add(mapping.SourceKeyName, mapping);
            }

            return(modelMappingDictionary);
        }
Пример #2
0
        /// <summary>
        /// Reads the current appSettings section into a new instance of the model class type specified.
        /// </summary>
        /// <param name="modelType">Type of the model.</param>
        /// <param name="errors">When an errors collection is supplied, then throwing is suppressed and instead the errors collection is populated.</param>
        /// <returns>
        /// An instance of the type specified.
        /// </returns>
        /// <exception cref="ArgumentNullException">modelType</exception>
        /// <exception cref="Evoq.Configuration.InvalidConfigurationModelException">
        /// </exception>
        /// <exception cref="InvalidConfigurationModelException"></exception>
        public object ReadInto(Type modelType, ICollection <ConfigurationModelValidationError> errors)
        {
            if (modelType == null)
            {
                throw new ArgumentNullException(nameof(modelType));
            }

            bool throwOnValidationErrors = (errors == null); // If we were not supplied with a bucket in which to stick errors, we must throw.

            var modelMappings = ModelMappingDictionary.CreateFrom(modelType);

            if (modelMappings.Any())
            {
                object model;

                model = this.CreateModelInstanceOrThrow(modelType);

                foreach (var mapping in modelMappings.Values)
                {
                    try
                    {
                        // SetValue will throw given the wrong type for the model property.

                        object sourceValue = this.GetSourceValue(mapping);

                        mapping.PropertyInfo.SetValue(model, sourceValue);
                    }
                    catch (InvalidOperationException notValidException) when(notValidException.Message.Contains("not a valid"))
                    {
                        // Invalid type cast/convert.

                        if (throwOnValidationErrors)
                        {
                            throw new InvalidConfigurationModelException($"Cannot read the settings into {modelType.Name}.{mapping.ModelPropertyName}. {notValidException.Message}", notValidException);
                        }
                        else
                        {
                            errors.Add(new ConfigurationModelValidationError(notValidException.Message, new string[] { mapping.ModelPropertyName }));
                        }
                    }
                    catch (KeyNotFoundException)
                    {
                        // Missing. We can swallow the problem here and allow later validation step to deal with it.
                    }
                    catch (InvalidOperationException)
                    {
                        // Missing. We can swallow the problem here and allow later validation step to deal with it.
                    }
                }

                IEnumerable <ConfigurationModelValidationError> validationErrors = null;
                bool isValid = this.ModelValidator.TryValidateModel(model, out validationErrors);
                if (!isValid)
                {
                    // Invalid.

                    if (throwOnValidationErrors)
                    {
                        string message;

                        if (validationErrors.Count() == 1)
                        {
                            message = $"Cannot read the settings into {modelType.Name}. {validationErrors.First().ErrorMessage}";
                        }
                        else
                        {
                            message = $"Cannot read the settings into {modelType.Name}. There are {validationErrors.Count()} validation errors.";
                        }

                        throw new InvalidConfigurationModelException(message)
                              {
                                  ValidationErrors = validationErrors
                              };
                    }
                    else
                    {
                        foreach (var error in validationErrors)
                        {
                            errors.Add(error);
                        }
                    }
                }

                return(model);
            }
            else
            {
                throw new InvalidConfigurationModelException($"Cannot read the appSettings section. The model class {modelType.Name} has no public properties.");
            }
        }