private List <ConfigurationProperty> GetConfigurationPropertiesInternal(Type type) { var configurationProperties = from property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance) let configurationEntryAttribute = property.GetCustomAttributes <ConfigurationEntryAttribute>().FirstOrDefault() where configurationEntryAttribute != null // filter out properties which aren't marked as configuration entry orderby configurationEntryAttribute.Order // properties are initialized in order of declaration select property; var results = new List <ConfigurationProperty>(); foreach (var property in configurationProperties) { ValidateProperty(property); var attributes = property.GetCustomAttributes <ConfigurationEntryAttribute>().OrderBy(order => order.Order).ToList(); var defaultValueAttribute = property.GetCustomAttribute <DefaultValueAttribute>(); var minValueAttribute = property.GetCustomAttribute <MinValueAttribute>(); TimeUnitAttribute timeUnit = null; SizeUnitAttribute sizeUnit = null; if (property.PropertyType == typeof(TimeSetting) || property.PropertyType == typeof(TimeSetting?)) { timeUnit = property.GetCustomAttribute <TimeUnitAttribute>(); Debug.Assert(timeUnit != null); } else if (property.PropertyType == typeof(Size) || property.PropertyType == typeof(Size?)) { sizeUnit = property.GetCustomAttribute <SizeUnitAttribute>(); Debug.Assert(sizeUnit != null); } var item = new ConfigurationProperty { Info = property, ConfigurationEntryAttributes = attributes, DefaultValueAttribute = defaultValueAttribute, MinValueAttribute = minValueAttribute, TimeUnitAttribute = timeUnit, SizeUnitAttribute = sizeUnit }; results.Add(item); } return(results); }
public void Initialize(Func <string, SettingValue> getSetting, string serverDataDir, ResourceType type, string resourceName, bool throwIfThereIsNoSetMethod) { foreach (var property in GetConfigurationProperties()) { if (property.Info.SetMethod == null) { if (throwIfThereIsNoSetMethod) { throw new InvalidOperationException($"No set method available for '{property.Info.Name}' property.Info."); } continue; } TimeUnitAttribute timeUnit = property.TimeUnitAttribute; SizeUnitAttribute sizeUnit = property.SizeUnitAttribute; var configuredValueSet = false; var setDefaultValueIfNeeded = true; ConfigurationEntryAttribute previousAttribute = null; foreach (var entry in property.Info.GetCustomAttributes <ConfigurationEntryAttribute>().OrderBy(order => order.Order)) { if (previousAttribute != null && previousAttribute.Scope != entry.Scope) { throw new InvalidOperationException($"All ConfigurationEntryAttribute for {property.Info.Name} must have the same Scope"); } previousAttribute = entry; var settingValue = getSetting(entry.Key); if (type != ResourceType.Server && entry.Scope == ConfigurationEntryScope.ServerWideOnly && settingValue.CurrentValue != null) { throw new InvalidOperationException($"Configuration '{entry.Key}' can only be set at server level."); } string value = null; if (settingValue.KeyExistsInDatabaseRecord) { value = settingValue.CurrentValue; if (value == null && property.Info.Type() == typeof(PathSetting)) { // for backward compatibility purposes let's ignore null on PathSetting and default to server value - RavenDB-15384 value = settingValue.ServerValue; } } else if (settingValue.KeyExistsInServerSettings) { value = settingValue.ServerValue; } setDefaultValueIfNeeded &= entry.SetDefaultValueIfNeeded; if (value == null) { continue; } value = value.Trim(); try { var minValue = property.MinValueAttribute; if (minValue == null) { if (property.Info.PropertyType.IsEnum) { object parsedValue; try { parsedValue = Enum.Parse(property.Info.PropertyType, value, true); } catch (ArgumentException) { throw new ConfigurationEnumValueException(value, property.Info.PropertyType); } property.Info.SetValue(this, parsedValue); } else if (property.Info.PropertyType == typeof(string[])) { var values = SplitValue(value); property.Info.SetValue(this, values); } else if (property.Info.PropertyType.IsArray && property.Info.PropertyType.GetElementType().IsEnum) { var values = SplitValue(value) .Select(item => Enum.Parse(property.Info.PropertyType.GetElementType(), item, ignoreCase: true)) .ToArray(); var enumValues = Array.CreateInstance(property.Info.PropertyType.GetElementType(), values.Length); Array.Copy(values, enumValues, enumValues.Length); property.Info.SetValue(this, enumValues); } else if (property.Info.PropertyType == typeof(HashSet <string>)) { var hashSet = new HashSet <string>(SplitValue(value), StringComparer.OrdinalIgnoreCase); property.Info.SetValue(this, hashSet); } else if (property.Info.PropertyType == typeof(UriSetting[])) { var values = SplitValue(value); UriSetting[] settings = new UriSetting[values.Length]; for (var i = 0; i < values.Length; i++) { settings[i] = new UriSetting(values[i]); } property.Info.SetValue(this, settings); } else if (timeUnit != null) { property.Info.SetValue(this, new TimeSetting(Convert.ToInt64(value), timeUnit.Unit)); } else if (sizeUnit != null) { property.Info.SetValue(this, new Size(Convert.ToInt64(value), sizeUnit.Unit)); } else { var t = Nullable.GetUnderlyingType(property.Info.PropertyType) ?? property.Info.PropertyType; if (property.Info.PropertyType == typeof(PathSetting)) { property.Info.SetValue(this, settingValue.CurrentValue != null ? new PathSetting(Convert.ToString(value), serverDataDir) : new PathSetting(Convert.ToString(value), type, resourceName)); } else if (property.Info.PropertyType == typeof(PathSetting[])) { var paths = SplitValue(value); property.Info.SetValue(this, settingValue.CurrentValue != null ? paths.Select(x => new PathSetting(Convert.ToString(x), serverDataDir)).ToArray() : paths.Select(x => new PathSetting(Convert.ToString(x), type, resourceName)).ToArray()); } else if (t == typeof(UriSetting)) { property.Info.SetValue(this, new UriSetting(value)); } else { var safeValue = Convert.ChangeType(value, t); property.Info.SetValue(this, safeValue); } } } else { if (property.Info.PropertyType == typeof(int) || property.Info.PropertyType == typeof(int?)) { property.Info.SetValue(this, Math.Max(Convert.ToInt32(value), minValue.Int32Value)); } else if (property.Info.PropertyType == typeof(Size) || property.Info.PropertyType == typeof(Size?)) { property.Info.SetValue(this, new Size(Math.Max(Convert.ToInt32(value), minValue.Int32Value), sizeUnit.Unit)); } else if (property.Info.PropertyType == typeof(TimeSetting) || property.Info.PropertyType == typeof(TimeSetting?)) { property.Info.SetValue(this, new TimeSetting(Math.Max(Convert.ToInt32(value), minValue.Int32Value), timeUnit.Unit)); } else { throw new NotSupportedException("Min value for " + property.Info.PropertyType + " is not supported. Property name: " + property.Info.Name); } } } catch (Exception e) { throw new InvalidOperationException($"Could not set '{entry.Key}' configuration setting value.", e); } configuredValueSet = true; break; } if (configuredValueSet || setDefaultValueIfNeeded == false) { continue; } var defaultValueAttribute = property.DefaultValueAttribute; if (defaultValueAttribute == null) { throw new InvalidOperationException($"Property '{property.Info.Name}' does not have a default value attribute"); } var defaultValue = defaultValueAttribute.Value; if (DefaultValueSetInConstructor.Equals(defaultValue)) { continue; } if (timeUnit != null && defaultValue != null) { property.Info.SetValue(this, new TimeSetting(Convert.ToInt64(defaultValue), timeUnit.Unit)); } else if (sizeUnit != null && defaultValue != null) { property.Info.SetValue(this, new Size(Convert.ToInt64(defaultValue), sizeUnit.Unit)); } else { if (property.Info.PropertyType == typeof(PathSetting) && defaultValue != null) { property.Info.SetValue(this, new PathSetting(Convert.ToString(defaultValue), type, resourceName)); } else if (property.Info.PropertyType == typeof(string[]) && defaultValue is string defaultValueAsString1) { var values = SplitValue(defaultValueAsString1); property.Info.SetValue(this, values); } else if (property.Info.PropertyType.IsArray && property.Info.PropertyType.GetElementType().IsEnum&& defaultValue is string defaultValueAsString2) { var values = SplitValue(defaultValueAsString2) .Select(item => Enum.Parse(property.Info.PropertyType.GetElementType(), item, ignoreCase: true)) .ToArray(); var enumValues = Array.CreateInstance(property.Info.PropertyType.GetElementType(), values.Length); Array.Copy(values, enumValues, enumValues.Length); property.Info.SetValue(this, enumValues); } else { property.Info.SetValue(this, defaultValue); } } } Initialized = true; }
public virtual void Initialize(NameValueCollection settings) { var configurationProperties = from property in GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance) let configurationEntryAttribute = property.GetCustomAttributes <ConfigurationEntryAttribute>().FirstOrDefault() where configurationEntryAttribute != null // filter out properties which aren't marked as configuration entry orderby configurationEntryAttribute.Order // properties are initialized in order of declaration select property; foreach (var property in configurationProperties) { TimeUnitAttribute timeUnit = null; SizeUnitAttribute sizeUnit = null; if (property.PropertyType == TimeSetting.TypeOf || property.PropertyType == TimeSetting.NullableTypeOf) { timeUnit = property.GetCustomAttribute <TimeUnitAttribute>(); Debug.Assert(timeUnit != null); } else if (property.PropertyType == Size.TypeOf || property.PropertyType == Size.NullableTypeOf) { sizeUnit = property.GetCustomAttribute <SizeUnitAttribute>(); Debug.Assert(sizeUnit != null); } var configuredValueSet = false; foreach (var entry in property.GetCustomAttributes <ConfigurationEntryAttribute>()) { var value = settings[entry.Key]; if (value == null) { continue; } try { var minValue = property.GetCustomAttribute <MinValueAttribute>(); if (minValue == null) { if (property.PropertyType.IsEnum) { property.SetValue(this, Enum.Parse(property.PropertyType, value, true)); } else if (timeUnit != null) { property.SetValue(this, new TimeSetting(Convert.ToInt64(value), timeUnit.Unit)); } else if (sizeUnit != null) { property.SetValue(this, new Size(Convert.ToInt64(value), sizeUnit.Unit)); } else { var t = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType; var safeValue = (value == null) ? null : Convert.ChangeType(value, t); property.SetValue(this, safeValue); } } else { if (property.PropertyType == typeof(int) || property.PropertyType == typeof(int?)) { property.SetValue(this, Math.Max(Convert.ToInt32(value), minValue.Int32Value)); } else if (property.PropertyType == Size.TypeOf) { property.SetValue(this, new Size(Math.Max(Convert.ToInt32(value), minValue.Int32Value), sizeUnit.Unit)); } else { throw new NotSupportedException("Min value for " + property.PropertyType + " is not supported. Property name: " + property.Name); } } } catch (Exception e) { throw new InvalidOperationException("Could not set configuration value given under the following setting: " + entry.Key, e); } configuredValueSet = true; break; } if (configuredValueSet) { continue; } var defaultValueAttribute = property.GetCustomAttribute <DefaultValueAttribute>(); if (defaultValueAttribute == null) { throw new InvalidOperationException($"Property '{property.Name}' does not have a default value attribute"); } var defaultValue = defaultValueAttribute.Value; if (DefaultValueSetInConstructor.Equals(defaultValue)) { continue; } if (timeUnit != null && defaultValue != null) { property.SetValue(this, new TimeSetting(Convert.ToInt64(defaultValue), timeUnit.Unit)); } else if (sizeUnit != null && defaultValue != null) { property.SetValue(this, new Size(Convert.ToInt64(defaultValue), sizeUnit.Unit)); } else { property.SetValue(this, defaultValue); } } Initialized = true; }
public void Initialize(Func <string, SettingValue> getSetting, string serverDataDir, ResourceType type, string resourceName, bool throwIfThereIsNoSetMethod) { foreach (var property in GetConfigurationProperties()) { if (property.SetMethod == null) { if (throwIfThereIsNoSetMethod) { throw new InvalidOperationException($"No set method available for '{property.Name}' property."); } continue; } ValidateProperty(property); TimeUnitAttribute timeUnit = null; SizeUnitAttribute sizeUnit = null; if (property.PropertyType == TimeSetting.TypeOf || property.PropertyType == TimeSetting.NullableTypeOf) { timeUnit = property.GetCustomAttribute <TimeUnitAttribute>(); Debug.Assert(timeUnit != null); } else if (property.PropertyType == Size.TypeOf || property.PropertyType == Size.NullableTypeOf) { sizeUnit = property.GetCustomAttribute <SizeUnitAttribute>(); Debug.Assert(sizeUnit != null); } var configuredValueSet = false; var setDefaultValueOfNeeded = true; foreach (var entry in property.GetCustomAttributes <ConfigurationEntryAttribute>()) { var settingValue = getSetting(entry.Key); if (type != ResourceType.Server && entry.Scope == ConfigurationEntryScope.ServerWideOnly && settingValue.CurrentValue != null) { throw new InvalidOperationException($"Configuration '{entry.Key}' can only be set at server level."); } var value = settingValue.CurrentValue ?? settingValue.ServerValue; setDefaultValueOfNeeded &= entry.SetDefaultValueIfNeeded; if (value == null) { continue; } try { var minValue = property.GetCustomAttribute <MinValueAttribute>(); if (minValue == null) { if (property.PropertyType.GetTypeInfo().IsEnum) { object parsedValue; try { parsedValue = Enum.Parse(property.PropertyType, value, true); } catch (ArgumentException) { throw new ConfigurationEnumValueException(value, property.PropertyType); } property.SetValue(this, parsedValue); } else if (property.PropertyType == typeof(string[])) { var values = value.Split(';'); property.SetValue(this, values); } else if (timeUnit != null) { property.SetValue(this, new TimeSetting(Convert.ToInt64(value), timeUnit.Unit)); } else if (sizeUnit != null) { property.SetValue(this, new Size(Convert.ToInt64(value), sizeUnit.Unit)); } else { var t = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType; if (property.PropertyType == typeof(PathSetting)) { property.SetValue(this, settingValue.CurrentValue != null ? new PathSetting(Convert.ToString(value), serverDataDir) : new PathSetting(Convert.ToString(value), type, resourceName)); } else if (property.PropertyType == typeof(PathSetting[])) { var paths = value.Split(';'); property.SetValue(this, settingValue.CurrentValue != null ? paths.Select(x => new PathSetting(Convert.ToString(x), serverDataDir)).ToArray() : paths.Select(x => new PathSetting(Convert.ToString(x), type, resourceName)).ToArray()); } else if (t == typeof(UriSetting)) { property.SetValue(this, new UriSetting(value)); } else { var safeValue = value == null ? null : Convert.ChangeType(value, t); property.SetValue(this, safeValue); } } } else { if (property.PropertyType == typeof(int) || property.PropertyType == typeof(int?)) { property.SetValue(this, Math.Max(Convert.ToInt32(value), minValue.Int32Value)); } else if (property.PropertyType == Size.TypeOf) { property.SetValue(this, new Size(Math.Max(Convert.ToInt32(value), minValue.Int32Value), sizeUnit.Unit)); } else { throw new NotSupportedException("Min value for " + property.PropertyType + " is not supported. Property name: " + property.Name); } } } catch (Exception e) { throw new InvalidOperationException($"Could not set '{entry.Key}' configuration setting value.", e); } configuredValueSet = true; break; } if (configuredValueSet || setDefaultValueOfNeeded == false) { continue; } var defaultValueAttribute = property.GetCustomAttribute <DefaultValueAttribute>(); if (defaultValueAttribute == null) { throw new InvalidOperationException($"Property '{property.Name}' does not have a default value attribute"); } var defaultValue = defaultValueAttribute.Value; if (DefaultValueSetInConstructor.Equals(defaultValue)) { continue; } if (timeUnit != null && defaultValue != null) { property.SetValue(this, new TimeSetting(Convert.ToInt64(defaultValue), timeUnit.Unit)); } else if (sizeUnit != null && defaultValue != null) { property.SetValue(this, new Size(Convert.ToInt64(defaultValue), sizeUnit.Unit)); } else { if (property.PropertyType == typeof(PathSetting) && defaultValue != null) { property.SetValue(this, new PathSetting(Convert.ToString(defaultValue), type, resourceName)); } else { property.SetValue(this, defaultValue); } } } Initialized = true; }
public void Initialize(Func <string, string> getSetting, bool throwIfThereIsNoSetMethod) { foreach (var property in GetConfigurationProperties()) { if (property.SetMethod == null) { if (throwIfThereIsNoSetMethod) { throw new InvalidOperationException($"No set method available for '{property.Name}' property."); } continue; } ValidateProperty(property); TimeUnitAttribute timeUnit = null; SizeUnitAttribute sizeUnit = null; if (property.PropertyType == TimeSetting.TypeOf || property.PropertyType == TimeSetting.NullableTypeOf) { timeUnit = property.GetCustomAttribute <TimeUnitAttribute>(); Debug.Assert(timeUnit != null); } else if (property.PropertyType == Size.TypeOf || property.PropertyType == Size.NullableTypeOf) { sizeUnit = property.GetCustomAttribute <SizeUnitAttribute>(); Debug.Assert(sizeUnit != null); } var configuredValueSet = false; var setDefaultValueOfNeeded = true; foreach (var entry in property.GetCustomAttributes <ConfigurationEntryAttribute>()) { var value = getSetting(entry.Key); setDefaultValueOfNeeded &= entry.SetDefaultValueIfNeeded; if (value == null) { continue; } try { var minValue = property.GetCustomAttribute <MinValueAttribute>(); if (minValue == null) { if (property.PropertyType.GetTypeInfo().IsEnum) { property.SetValue(this, Enum.Parse(property.PropertyType, value, true)); } if (property.PropertyType == typeof(string[])) { var values = value.Split(';'); property.SetValue(this, values); } else if (timeUnit != null) { property.SetValue(this, new TimeSetting(Convert.ToInt64(value), timeUnit.Unit)); } else if (sizeUnit != null) { property.SetValue(this, new Size(Convert.ToInt64(value), sizeUnit.Unit)); } else { var t = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType; var safeValue = (value == null) ? null : Convert.ChangeType(value, t); property.SetValue(this, safeValue); } } else { if (property.PropertyType == typeof(int) || property.PropertyType == typeof(int?)) { property.SetValue(this, Math.Max(Convert.ToInt32(value), minValue.Int32Value)); } else if (property.PropertyType == Size.TypeOf) { property.SetValue(this, new Size(Math.Max(Convert.ToInt32(value), minValue.Int32Value), sizeUnit.Unit)); } else { throw new NotSupportedException("Min value for " + property.PropertyType + " is not supported. Property name: " + property.Name); } } } catch (Exception e) { throw new InvalidOperationException("Could not set configuration value given under the following setting: " + entry.Key, e); } configuredValueSet = true; break; } if (configuredValueSet || setDefaultValueOfNeeded == false) { continue; } var defaultValueAttribute = property.GetCustomAttribute <DefaultValueAttribute>(); if (defaultValueAttribute == null) { throw new InvalidOperationException($"Property '{property.Name}' does not have a default value attribute"); } var defaultValue = defaultValueAttribute.Value; if (DefaultValueSetInConstructor.Equals(defaultValue)) { continue; } if (timeUnit != null && defaultValue != null) { property.SetValue(this, new TimeSetting(Convert.ToInt64(defaultValue), timeUnit.Unit)); } else if (sizeUnit != null && defaultValue != null) { property.SetValue(this, new Size(Convert.ToInt64(defaultValue), sizeUnit.Unit)); } else { property.SetValue(this, defaultValue); } } Initialized = true; }