/// <summary> /// Sets the setting with the specified name (supports custom types using the specified converters). /// Creates a new setting, if it does not exist, yet. /// </summary> /// <typeparam name="T">Type of the setting.</typeparam> /// <param name="name"> /// Name of the setting. The following characters are allowed: /// - alphanumeric characters ( a-z, A-Z, 0-9 ) /// - square brackets ( [] ) /// - Period (.) /// </param> /// <param name="value">New value of the setting.</param> /// <param name="valueToStringConverter">Delegate that converts the object to its string representation.</param> /// <param name="stringToValueConverter">Delegate that converts the string representation to an object of the type <typeparamref name="T"/>.</param> /// <returns>The setting.</returns> /// <exception cref="ArgumentNullException"> /// The argument <paramref name="name"/>, <paramref name="valueToStringConverter"/> and/or <paramref name="stringToValueConverter"/> is <c>null</c>. /// </exception> /// <exception cref="ArgumentException"> /// The setting exists already, but the specified type differs from the value type of the existing setting. /// </exception> /// <exception cref="FormatException"> /// The <paramref name="name"/> is not a valid setting name. /// </exception> public override IProcessingPipelineStageSetting <T> SetSetting <T>( string name, T value, ObjectToStringConversionDelegate <T> valueToStringConverter, StringToObjectConversionDelegate <T> stringToValueConverter) { // check arguments if (valueToStringConverter == null) { throw new ArgumentNullException(nameof(valueToStringConverter)); } if (stringToValueConverter == null) { throw new ArgumentNullException(nameof(stringToValueConverter)); } CheckSettingName(name); lock (Sync) { if (!mSettings.TryGetValue(name, out var setting)) { // the setting with the specified name was not requested before // => create a new setting setting = new VolatileProcessingPipelineStageSetting <T>(this, name, valueToStringConverter, stringToValueConverter); mSettings.Add(name, setting); } // setting with the same name exists // ensure that the setting value types are the same if (setting.ValueType != typeof(T)) { string message = $"The setting exists already, but the specified types ({typeof(T).FullName}) differs from the value type of the existing setting ({setting.ValueType.FullName})."; throw new ArgumentException(message); } // set the value of the setting setting.Value = value; return((IProcessingPipelineStageSetting <T>)setting); } }
/// <summary> /// Registers the setting with the specified name (supports custom types using the specified converters). /// Creates a new setting with the specified value, if the setting does not exist. /// </summary> /// <typeparam name="T">Type of the setting.</typeparam> /// <param name="name"> /// Name of the setting. The following characters are allowed: /// - alphanumeric characters ( a-z, A-Z, 0-9 ) /// - square brackets ( [] ) /// - Period (.) /// </param> /// <param name="defaultValue">Value of the setting, if the setting does not exist, yet.</param> /// <param name="valueToStringConverter">Delegate that converts a setting value to its string representation.</param> /// <param name="stringToValueConverter">Delegate that converts the string representation of a setting value to an object of the specified type.</param> /// <returns>The setting.</returns> /// <exception cref="ArgumentNullException"> /// The argument <paramref name="name"/>, <paramref name="valueToStringConverter"/> and/or <paramref name="stringToValueConverter"/> is <c>null</c>. /// </exception> /// <exception cref="ArgumentException"> /// The setting exists already, but the specified type differs from the value type of the existing setting. /// </exception> /// <exception cref="FormatException"> /// The <paramref name="name"/> is not a valid setting name. /// </exception> public override IProcessingPipelineStageSetting <T> RegisterSetting <T>( string name, T defaultValue, ObjectToStringConversionDelegate <T> valueToStringConverter, StringToObjectConversionDelegate <T> stringToValueConverter) { // check arguments if (valueToStringConverter == null) { throw new ArgumentNullException(nameof(valueToStringConverter)); } if (stringToValueConverter == null) { throw new ArgumentNullException(nameof(stringToValueConverter)); } CheckSettingName(name); lock (Sync) { bool isNewSetting = false; if (!mSettings.TryGetValue(name, out var setting)) { // the setting with the specified name was not requested before // => create a new setting isNewSetting = true; setting = new VolatileProcessingPipelineStageSetting <T>(this, name, valueToStringConverter, stringToValueConverter); mSettings.Add(name, setting); } // ensure that the setting value types are the same if (setting.ValueType != typeof(T)) { string message = $"The setting exists already, but the specified types ({typeof(T).FullName}) differs from the value type of the existing setting ({setting.ValueType.FullName})."; throw new ArgumentException(message); } // set the default value of the raw item, if it is not already set // (this can happen, if a setting has been created without a default value before) if (!setting.HasDefaultValue) { ((VolatileProcessingPipelineStageSetting <T>)setting).DefaultValue = defaultValue; } // ensure that the setting default values are the same string settingDefaultValueAsString = valueToStringConverter(((VolatileProcessingPipelineStageSetting <T>)setting).DefaultValue, CultureInfo.InvariantCulture); string defaultValueAsString = valueToStringConverter(defaultValue, CultureInfo.InvariantCulture); if (settingDefaultValueAsString != defaultValueAsString) { string message = $"The setting exists already, but the specified default value ({defaultValueAsString}) does not match the default value of the existing setting ({settingDefaultValueAsString})."; throw new ArgumentException(message); } // the setting with the specified name has been registered successfully // => notify, if a new setting was added (changes are handled differently) if (isNewSetting) { LogConfiguration.OnChanged(); } return((IProcessingPipelineStageSetting <T>)setting); } }