コード例 #1
0
        public static void Bind(this IConfiguration configuration, string path, object instance)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException(nameof(path));
            }

            configuration.GetSection(ConfigurationUtility.GetConfigurationPath(path)).Bind(instance);
        }
コード例 #2
0
        public ConfigurationRecognizer(PropertyInfo unrecognizedProperty)
        {
            _unrecognizedProperty = unrecognizedProperty ?? throw new ArgumentNullException(nameof(unrecognizedProperty));
            _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));
            }
        }
コード例 #3
0
            public PropertyToken(PropertyInfo property)
            {
                this.Property  = property;
                this.Converter = ConfigurationUtility.GetConverter(property);

                var attribute = property.GetCustomAttribute <ConfigurationPropertyAttribute>(true);

                if (attribute == null)
                {
                    this.Alias = property.Name;
                }
                else
                {
                    this.Alias = attribute.Name;
                }
            }
コード例 #4
0
        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);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        protected virtual object CreateInstance(Type type)
        {
            if (type.IsArray)
            {
                if (type.GetArrayRank() > 1)
                {
                    throw new InvalidOperationException(string.Format(Properties.Resources.Error_UnsupportedMultidimensionalArray, type));
                }

                return(Array.CreateInstance(type.GetElementType(), 0));
            }

            if (type.IsInterface)
            {
                var contract = ConfigurationUtility.GetImplementedContract(type,
                                                                           typeof(IReadOnlyDictionary <,>),
                                                                           typeof(IDictionary <,>));

                if (contract != null)
                {
                    var dictionaryType = typeof(Dictionary <,>).MakeGenericType(contract.GenericTypeArguments[0], contract.GenericTypeArguments[1]);
                    return(dictionaryType.GenericTypeArguments[0] != typeof(string) ?
                           Activator.CreateInstance(dictionaryType) :
                           Activator.CreateInstance(dictionaryType, new object[] { StringComparer.OrdinalIgnoreCase }));
                }

                contract = ConfigurationUtility.GetImplementedContract(type, typeof(ISet <>));

                if (contract != null)
                {
                    var setType = typeof(HashSet <>).MakeGenericType(contract.GenericTypeArguments[0]);
                    return(Activator.CreateInstance(setType));
                }

                contract = ConfigurationUtility.GetImplementedContract(type,
                                                                       typeof(IReadOnlyList <>),
                                                                       typeof(IList <>),
                                                                       typeof(IReadOnlyCollection <>),
                                                                       typeof(ICollection <>),
                                                                       typeof(IEnumerable <>));

                if (contract != null)
                {
                    var listType = typeof(List <>).MakeGenericType(contract.GenericTypeArguments[0]);
                    return(Activator.CreateInstance(listType));
                }
            }

            try
            {
                if (type.IsInterface || type.IsAbstract)
                {
                    return(Zongsoft.Data.Model.Build(type));
                }

                return(Activator.CreateInstance(type));
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException(string.Format(Properties.Resources.Error_FailedToActivate, type), ex);
            }
        }
コード例 #7
0
        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);
            }
        }
コード例 #8
0
        private void SetDictionaryValue(object dictionary, IConfigurationSection configuration)
        {
            if (configuration.Value == null)
            {
                foreach (var child in configuration.GetChildren())
                {
                    this.SetDictionaryValue(dictionary, child);
                }
            }

            if (dictionary != null && Common.Convert.TryConvertValue(configuration.Value, _dictionaryType.GenericTypeArguments[1], () => ConfigurationUtility.GetConverter(_unrecognizedProperty), out var convertedValue))
            {
                Reflection.Reflector.SetValue(ref dictionary, "Item", convertedValue, new object[] { configuration.Key });
            }
        }
コード例 #9
0
        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);
                    }
                }
            }
        }