DefaultableCollection

The DefaultableCollection class provides a flexible and efficient way to manage configuration settings that can be overwritten by user-specified values.

Rationale:

This class addresses a frequent challenge in .NET configuration management, where settings should be defined as default values that can be replaced by user configurations rather than being appended to. This approach is ideal for scenarios where user settings override system defaults.

Implementation Details:

DefaultableCollection implements the ICollection interface, offering methods to manage its contents. The core behavior is facilitated by internal dictionaries that store both default and user-specified values:

  • defaults - A Dictionary<TKey, TValue> containing the default values for each configuration setting.
  • overrides - A Dictionary<TKey, TValue> containing the values specified by the user, which override the defaults.

Key Features:

  1. Overriding Defaults:

    The DefaultableCollection prioritizes user-defined values over default values. When retrieving a value, the overrides dictionary is checked first. If the key is present, its associated value is returned. If not, the defaults dictionary is consulted, and its corresponding value is returned.

    public TValue this[TKey key] {
                get {
                  if (overrides.ContainsKey(key)) {
                    return overrides[key];
                  } else if (defaults.ContainsKey(key)) {
                    return defaults[key];
                  } else {
                    throw new KeyNotFoundException();
                  }
                }
                set {
                  overrides[key] = value;
                }
              }
              

    Source: DefaultableCollection.cs

  2. Initialization and Configuration:

    You can initialize a DefaultableCollection by providing the default values in its constructor:

    var collection = new DefaultableCollection<string, int>(new Dictionary<string, int>
              {
                { "key1", 10 },
                { "key2", 20 }
              });
              

    Later, you can modify or add to the default values using the DefaultValues property:

    collection.DefaultValues.Add("key3", 30);
              

    User-specific values can be set through the Overrides property, overwriting default values:

    collection.Overrides.Add("key1", 15);
              

Usage Examples:

  1. Retrieving a Value:

    // Access a key that has both a default and an override value.
              int value = collection["key1"]; // Returns 15 (override value)
              
  2. Updating a Value:

    // Update an existing override value.
              collection["key1"] = 25;
              
  3. Iterating through Values:

    foreach (var item in collection)
              {
                Console.WriteLine($"Key: {item.Key}, Value: {item.Value}");
              }
              

Key Points:

  • DefaultableCollection prioritizes user-specified overrides over default values.
  • The Overrides property facilitates the addition or modification of user-defined values.
  • The DefaultValues property allows modification of the default values.
  • The ICollection interface enables standard operations like adding, removing, and iterating through the collection.