public object Resolve(Type type, IConfiguration configuration, ConfigurationBinderOptions options) { if (type == null) { throw new ArgumentNullException(nameof(type)); } var instance = this.CreateInstance(type); this.Resolve(instance, configuration, options); return(instance); }
private void ResolveInstance(object instance, IConfiguration configuration, ConfigurationBinderOptions options) { if (configuration is IConfigurationSection section) { var properties = this.GetProperties(instance.GetType().GetTypeInfo()); if (section.Value != null) { if (properties.TryGetValue(section.Key, out var property)) { if (SetPathInfo(instance, property, section)) { return; } if (property.SetValue(instance, section.Value)) { return; } throw new InvalidOperationException(string.Format(Properties.Resources.Error_FailedBinding, section.Path, property.PropertyType)); } this.OnUnrecognize(instance, properties, section, options); } else { if (properties.TryGetValue(section.Key, out var property)) { var target = property.GetValue(instance); if (target == null) { target = this.Resolve(property.PropertyType, configuration, options); } else { this.Resolve(target, configuration, options); } property.SetValue(instance, target); } else { if (!this.ResolveCollection(instance, section, properties, options)) { this.OnUnrecognize(instance, properties, section, options); } } } } }
public static void Bind(this IConfiguration configuration, object instance, Action <ConfigurationBinderOptions> configureOptions) { if (configuration == null) { throw new ArgumentNullException(nameof(configuration)); } if (instance != null) { var options = new ConfigurationBinderOptions(); configureOptions?.Invoke(options); GetResolver(instance.GetType()).Resolve(instance, configuration, options); } }
public void Resolve(object instance, IConfiguration configuration, ConfigurationBinderOptions options) { if (instance == null) { throw new ArgumentNullException(nameof(instance)); } var type = instance.GetType(); if (type == typeof(IConfigurationSection)) { return; } foreach (var child in configuration.GetChildren()) { this.ResolveInstance(instance, child, options); } }
public bool Recognize(object target, IConfigurationSection configuration, ConfigurationBinderOptions options) { if (target == null) { return(false); } var unrecognizedProperty = _unrecognizedProperty; var dictionary = Reflection.Reflector.GetValue(unrecognizedProperty, ref target); if (dictionary == null) { if (!unrecognizedProperty.CanWrite) { throw new ConfigurationException($"The {unrecognizedProperty.Name} unrecognized property value is null and it is read-only."); } if (unrecognizedProperty.PropertyType.IsAbstract) { var dictionaryType = ConfigurationUtility.GetImplementedContract(unrecognizedProperty.PropertyType, typeof(IDictionary <,>))?.GetTypeInfo(); if (dictionaryType == null || dictionaryType.GenericTypeArguments[0] != typeof(string)) { throw new InvalidOperationException(string.Format(Properties.Resources.Error_InvalidUnrecognizedProperty, unrecognizedProperty.Name)); } dictionary = Activator.CreateInstance(typeof(Dictionary <,>).MakeGenericType(typeof(string), dictionaryType.GenericTypeArguments[1]), new object[] { StringComparer.OrdinalIgnoreCase }); } else { dictionary = Activator.CreateInstance(unrecognizedProperty.PropertyType); } Reflection.Reflector.SetValue(unrecognizedProperty, ref target, dictionary); } this.SetDictionaryValue(dictionary, configuration); return(true); }
private bool ResolveDefaultProperty(object instance, PropertyToken property, IDictionary <string, PropertyToken> properties, IConfigurationSection configuration, ConfigurationBinderOptions options) { if (property == null) { return(false); } var value = property.GetValue(instance); if (value == null) { if (!property.CanWrite) { return(false); } value = this.CreateInstance(property.PropertyType); if (!property.SetValue(instance, value)) { throw new ConfigurationException($"The default collection property {property.Name} of '{instance.GetType().FullName}' type is null and it cannot be set."); } } return(this.ResolveCollection(value, configuration, this.GetProperties(value.GetType().GetTypeInfo()), options)); }
protected virtual void OnUnrecognize(object target, IDictionary <string, PropertyToken> properties, IConfigurationSection configuration, ConfigurationBinderOptions options) { var unrecognizedProperty = ConfigurationRecognizerProvider.GetUnrecognizedProperty(target.GetType()); if (unrecognizedProperty == null) { if (configuration.Value == null && this.ResolveDefaultProperty(target, FindDefaultProperty(properties.Values), properties, configuration, options)) { return; } if (options !.UnrecognizedError) { throw new ConfigurationException($"The specified '{configuration.Path}' configuration section cannot be bound to a member of the '{target.GetType()}' type."); } return; } if (configuration.Value == null) { var attribute = unrecognizedProperty.GetCustomAttribute <ConfigurationPropertyAttribute>(true); //如果指定的未识别属性名被注解为空或星号,则表示它是一个默认集合属性 if (attribute != null && (string.IsNullOrEmpty(attribute.Name) || attribute.Name == "*")) { //解析默认集合成功则返回,否则抛出异常 if (this.ResolveDefaultProperty(target, properties[unrecognizedProperty.Name], properties, configuration, options)) { return; } throw new ConfigurationException($"The {unrecognizedProperty.Name} property of type '{target.GetType().FullName}' is annotated as the default collection, but the binding for this property fails."); } } var recognizers = this.Recognizers ?? ConfigurationRecognizerProvider.Default; var recognizer = recognizers.GetRecognize(target.GetType()) ?? throw new ConfigurationException($"Unable to get a recognizer of type '{target.GetType().FullName}'."); if (!recognizer.Recognize(target, configuration, options) && options !.UnrecognizedError) { throw new ConfigurationException($"The '{configuration.Path}' configuration section is not recognized."); } }
public void Attach(object instance, IConfiguration configuration, ConfigurationBinderOptions options) { if (instance == null) { throw new ArgumentNullException(nameof(instance)); } if (configuration == null) { throw new ArgumentNullException(nameof(configuration)); } var properties = this.GetProperties(instance.GetType().GetTypeInfo()).Values.Distinct().ToArray(); foreach (var property in properties) { if (Common.TypeExtension.IsScalarType(property.PropertyType)) { configuration[property.ConfigurationKey] = property.GetStringValue(instance); continue; } var propertyValue = property.GetValue(instance); var dictionaryType = ConfigurationUtility.GetImplementedContract( property.PropertyType, typeof(IReadOnlyDictionary <,>), typeof(IDictionary <,>)); if (dictionaryType != null) { //if(propertyValue.GetType() != dictionaryType) // this.Attach(propertyValue, configuration.GetSection(property.ConfigurationKey), options); foreach (DictionaryEntry entry in (IEnumerable)propertyValue) { var key = ConfigurationPath.Combine(property.ConfigurationKey, entry.Key.ToString()); this.Attach(entry.Value, configuration.GetSection(key), options); } continue; } var collectionType = ConfigurationUtility.GetImplementedContract( property.PropertyType, typeof(IReadOnlyCollection <>), typeof(ICollection <>), typeof(IEnumerable <>)); if (collectionType != null) { //if(propertyValue.GetType() != collectionType) // this.Attach(propertyValue, configuration.GetSection(property.ConfigurationKey), options); int index = 0; foreach (var entry in (IEnumerable)propertyValue) { var key = ConfigurationPath.Combine(property.ConfigurationKey, index++.ToString()); this.Attach(entry, configuration.GetSection(key), options); } continue; } this.Attach(propertyValue, configuration.GetSection(property.ConfigurationKey), options); } }
private bool ResolveCollection(object instance, IConfigurationSection configuration, IDictionary <string, PropertyToken> properties, ConfigurationBinderOptions options) { var dictionaryType = ConfigurationUtility.GetImplementedContract(instance.GetType(), typeof(IDictionary <,>)); if (dictionaryType != null) { object key = configuration.Key; //如果字典键类型不是字符串并且配置键文本转换失败则抛出异常 if (dictionaryType.GenericTypeArguments[0] != typeof(string) && !Common.Convert.TryConvertValue(key, dictionaryType.GenericTypeArguments[0], out key)) { throw new ConfigurationException($"Unable to convert the ‘{key}’ configuration key to a dictionary key type of ‘{dictionaryType.GenericTypeArguments[0].FullName}’ type."); } var valueType = dictionaryType.GenericTypeArguments[1]; var setter = dictionaryType.GetTypeInfo().GetDeclaredProperty("Item"); Reflection.Reflector.SetValue(setter, ref instance, this.Resolve(valueType, configuration, options), new object[] { key }); return(true); } var collectionType = ConfigurationUtility.GetImplementedContract(instance.GetType(), typeof(ICollection <>)); if (collectionType != null) { var valueType = collectionType.GenericTypeArguments[0]; var add = collectionType.GetTypeInfo().GetDeclaredMethod("Add"); add.Invoke(instance, new object[] { this.Resolve(valueType, configuration, options) }); return(true); } //返回失败 return(false); }
private void ResolveInstance(object instance, IConfiguration configuration, ConfigurationBinderOptions options) { if (configuration is IConfigurationSection section) { var properties = this.GetProperties(instance.GetType().GetTypeInfo()); if (section.Value != null) { if (properties.TryGetValue(section.Key, out var property)) { if (property.SetValue(instance, section.Value)) { return; } throw new InvalidOperationException(string.Format(Properties.Resources.Error_FailedBinding, section.Path, instance.GetType())); } this.OnUnrecognize(instance, section.Key, section.Value); } else { if (properties.TryGetValue(section.Key, out var property)) { var target = property.GetValue(instance); if (target == null) { target = this.Resolve(property.PropertyType, configuration, options); } else { this.Resolve(target, configuration, options); } property.SetValue(instance, target); } else { var dictionaryType = ConfigurationUtility.GetImplementedContract(instance.GetType(), typeof(IDictionary <,>)); if (dictionaryType != null) { if (dictionaryType.GenericTypeArguments[0] != typeof(string)) { return; } var valueType = dictionaryType.GenericTypeArguments[1]; var setter = dictionaryType.GetTypeInfo().GetDeclaredProperty("Item"); Reflection.Reflector.SetValue(setter, ref instance, this.Resolve(valueType, configuration, options), new object[] { section.Key }); return; } var collectionType = ConfigurationUtility.GetImplementedContract(instance.GetType(), typeof(ICollection <>)); if (collectionType != null) { var valueType = collectionType.GenericTypeArguments[0]; var add = collectionType.GetTypeInfo().GetDeclaredMethod("Add"); add.Invoke(instance, new object[] { this.Resolve(valueType, configuration, options) }); return; } this.OnUnrecognize(instance, configuration); } } } }