< Summary

Information
Class: AmbientServices.BasicAmbientSettingsSet
Assembly: AmbientServices
File(s): /home/runner/work/AmbientServices/AmbientServices/AmbientServices/DefaultImplementation/BasicAmbientSettings.cs
Tag: 332_35464845198
Line coverage
100%
Covered lines: 39
Uncovered lines: 0
Coverable lines: 39
Total lines: 147
Line coverage: 100%
Branch coverage
100%
Covered branches: 26
Total branches: 26
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor()100%11100%
.ctor(...)100%44100%
.ctor(...)100%88100%
NewSettingRegistered(...)100%22100%
GetRawValue(...)100%22100%
GetTypedValue(...)100%22100%
get_SettingsAreMutable()100%11100%
ChangeSetting(...)100%88100%
ToString()100%11100%

File(s)

/home/runner/work/AmbientServices/AmbientServices/AmbientServices/DefaultImplementation/BasicAmbientSettings.cs

#LineLine coverage
 1using System;
 2using System.Collections.Concurrent;
 3using System.Collections.Generic;
 4
 5namespace AmbientServices;
 6
 7/// <summary>
 8/// A basic settings set implementation that may be used for unit test dependency injection.
 9/// </summary>
 10/// <remarks>
 11/// <pitch>The zero-configuration, in-memory mutable settings set used unless overridden — well suited to unit-test depe
 12/// <pledge><see cref="IAmbientSettingsSet"/></pledge>
 13/// <plan>
 14/// Keeps raw values in one <see cref="ConcurrentDictionary{TKey,TValue}"/> and eagerly-converted typed values in a seco
 15/// </plan>
 16/// </remarks>
 17[DefaultAmbientService(typeof(IAmbientSettingsSet))]
 18public class BasicAmbientSettingsSet : IAmbientSettingsSet
 19{
 20    /// <summary>
 21    /// The set name of the default settings set.
 22    /// </summary>
 23    public const string DefaultSetName = "Default";
 24    private readonly LazyUnsubscribeWeakEventListenerProxy<BasicAmbientSettingsSet, object?, IAmbientSettingInfo> _weakS
 25    private readonly ConcurrentDictionary<string, string> _rawValues;
 26    private readonly ConcurrentDictionary<string, object> _typedValues;
 27
 28    /// <summary>
 29    /// Constructs the default ambient settings set.
 30    /// </summary>
 31    internal BasicAmbientSettingsSet()
 332        : this (DefaultSetName)
 33    {
 334    }
 35    /// <summary>
 36    /// Constructs a new ambient settings set with the specified values.
 37    /// </summary>
 38    /// <param name="name">The name of the set.</param>
 339    public BasicAmbientSettingsSet(string name)
 40    {
 341        SetName = name;
 342        _rawValues = new ConcurrentDictionary<string, string>();
 343        _typedValues = new ConcurrentDictionary<string, object>();
 344        _weakSettingRegistered = new LazyUnsubscribeWeakEventListenerProxy<BasicAmbientSettingsSet, object?, IAmbientSet
 245                this, NewSettingRegistered, wvc => SettingsRegistry.DefaultRegistry.SettingRegistered -= wvc.WeakEventHa
 346        SettingsRegistry.DefaultRegistry.SettingRegistered += _weakSettingRegistered.WeakEventHandler;
 347    }
 48    /// <summary>
 49    /// Constructs a new ambient settings set with the specified values.
 50    /// </summary>
 51    /// <param name="name">The name of the set.</param>
 52    /// <param name="values">A set of name-value pairs to use for the initial values for the set.</param>
 253    public BasicAmbientSettingsSet(string name, IDictionary<string, string> values)
 54    {
 255        SetName = name;
 256        _rawValues = new ConcurrentDictionary<string, string>(values);
 257        _typedValues = new ConcurrentDictionary<string, object>();
 258        if (values != null)
 59        {
 260            foreach (string key in values.Keys)
 61            {
 262                IAmbientSettingInfo? ps = SettingsRegistry.DefaultRegistry.TryGetSetting(key);
 263                _typedValues[key] = (ps != null) ? ps.Convert(this, values[key]) : values[key];
 64            }
 65        }
 266        _weakSettingRegistered = new LazyUnsubscribeWeakEventListenerProxy<BasicAmbientSettingsSet, object?, IAmbientSet
 267                this, NewSettingRegistered, wvc => SettingsRegistry.DefaultRegistry.SettingRegistered -= wvc.WeakEventHa
 268        SettingsRegistry.DefaultRegistry.SettingRegistered += _weakSettingRegistered.WeakEventHandler;
 269    }
 70
 71    private static void NewSettingRegistered(BasicAmbientSettingsSet settingsSet, object? sender, IAmbientSettingInfo se
 72    {
 73        // is there a value for this setting?
 74        string? value;
 375        if (settingsSet._rawValues.TryGetValue(setting.Key, out value))
 76        {
 77            // get the typed value
 278            settingsSet._typedValues[setting.Key] = setting.Convert(settingsSet, value);
 79        }
 380    }
 81
 82    /// <summary>
 83    /// Gets the name of the settings set so that a settings consumer can know where a changed setting value came from.
 84    /// </summary>
 85    public string SetName { get; }
 86    /// <summary>
 87    /// Gets the current raw (string) value for the specified key, or null if the setting is not set.
 88    /// </summary>
 89    /// <param name="key">A key identifying the setting whose value is to be retrieved.</param>
 90    /// <returns>The setting value, or null if the setting is not set.</returns>
 91
 92    public string? GetRawValue(string key)
 93    {
 94        string? value;
 295        return _rawValues.TryGetValue(key, out value) ? value : null;
 96    }
 97    /// <summary>
 98    /// Gets the current typed value for the setting with the specified key, or null if the setting is not set.
 99    /// </summary>
 100    /// <param name="key">A key identifying the setting whose value is to be retrieved.</param>
 101    /// <returns>The setting value, or null if the setting is not set.</returns>
 102    public object? GetTypedValue(string key)
 103    {
 104        object? value;
 3105        return _typedValues.TryGetValue(key, out value) ? value : null;
 106    }
 107    /// <summary>
 108    /// Gets whether or not the settings set is mutable.
 109    /// </summary>
 3110    public bool SettingsAreMutable => true;
 111    /// <summary>
 112    /// Changes the specified setting.
 113    /// For many ambient settings services, the value will only be reflected in memory until the process shuts down, but
 114    /// </summary>
 115    /// <param name="key">A string that uniquely identifies the setting.</param>
 116    /// <param name="value">The new string value for the setting, or null if the setting should be removed.</param>
 117    /// <returns>Whether or not the setting actually changed.</returns>
 118    public bool ChangeSetting(string key, string? value)
 119    {
 3120        if (value == null)
 121        {
 122            string? oldValue;
 2123            _rawValues.TryRemove(key, out oldValue);
 2124            _typedValues.TryRemove(key, out _);
 125            // did the value *not* change?  bail out early
 2126            if (oldValue == null) return false;
 127        }
 128        else
 129        {
 3130            string? oldValue = null;
 2131            _rawValues.AddOrUpdate(key, value, (k, v) => { oldValue = v; return value; });
 132            // did the value *not* change?  bail out early
 3133            if (string.Equals(value, oldValue, StringComparison.Ordinal)) return false;
 3134            IAmbientSettingInfo? ps = SettingsRegistry.DefaultRegistry.TryGetSetting(key);
 3135            _typedValues[key] = (ps != null) ? ps.Convert(this, value) : value;
 136        }
 3137        return true;
 138    }
 139    /// <summary>
 140    /// Gets a string representing the settings instance.
 141    /// </summary>
 142    /// <returns></returns>
 143    public override string ToString()
 144    {
 2145        return "Settings: " + SetName;
 146    }
 147}