< Summary

Information
Class: UIBlazor.Services.Settings.BaseSettingsProvider<T>
Assembly: UIBlazor
File(s): /home/runner/work/InvAit/InvAit/UIBlazor/Services/Settings/BaseSettingsProvider.cs
Tag: 71_26091983037
Line coverage
81%
Covered lines: 36
Uncovered lines: 8
Coverable lines: 44
Total lines: 107
Line coverage: 81.8%
Branch coverage
66%
Covered branches: 12
Total branches: 18
Branch coverage: 66.6%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_Current()100%11100%
.ctor(...)50%22100%
OnPropertyChanged(...)100%22100%
CallSaveTrigger()0%620%
SaveAsync()50%22100%
InitializeAsync()100%22100%
AfterInitAsync()100%210%
CopyProperties(...)75%88100%
Dispose()100%210%

File(s)

/home/runner/work/InvAit/InvAit/UIBlazor/Services/Settings/BaseSettingsProvider.cs

#LineLine coverage
 1using System.ComponentModel;
 2using System.Reflection;
 3
 4namespace UIBlazor.Services.Settings;
 5
 6public abstract class BaseSettingsProvider<TOptions> : IBaseSettingsProvider where TOptions : BaseOptions, new()
 7{
 8    private readonly ILocalStorageService _storage;
 9    private readonly string _storageKey;
 10    protected readonly Debouncer Debouncer;
 11    private bool _isInitializing;
 12    private readonly ILogger _logger;
 13
 31214    public TOptions Current { get; } = new();
 15
 7216    protected BaseSettingsProvider(
 7217        ILocalStorageService storage,
 7218        ILogger logger,
 7219        string storageKey,
 7220        TimeSpan? debounceDelay = null)
 21    {
 7222        _storage = storage;
 7223        _logger = logger;
 7224        _storageKey = storageKey;
 7225        Debouncer = new Debouncer(debounceDelay ?? TimeSpan.FromMilliseconds(750), SaveAsync);
 7226    }
 27
 28    private void OnPropertyChanged(object? sender, PropertyChangedEventArgs e)
 29    {
 330        if (_isInitializing)
 231            return;
 32
 133        Debouncer.Trigger();
 134    }
 35
 36    public void CallSaveTrigger()
 37    {
 038        if (_isInitializing)
 039            return;
 040        Debouncer.Trigger();
 041    }
 42
 43    public event Action? OnSaved;
 44
 45    /// <summary>
 46    /// Немедленное сохранение Current объекта.<br/>
 47    /// Автоматически вызывается при изменении любого свойства, которое использует <see cref="BaseOptions.SetIfChanged"/
 48    /// </summary>
 49    public virtual async Task SaveAsync()
 50    {
 2051        await _storage.SetItemAsync(_storageKey, Current);
 2052        OnSaved?.Invoke();
 2053    }
 54
 55    /// <summary>
 56    /// Загрузка настроек
 57    /// </summary>
 58    public async Task InitializeAsync()
 59    {
 3860        _isInitializing = true;
 61        try
 62        {
 3863            var saved = await _storage.TryGetItemAsync<TOptions>(_storageKey);
 3764            if (saved != null)
 65            {
 966                CopyProperties(saved, Current);
 67            }
 68
 3769            Current.PropertyChanged += OnPropertyChanged;
 3770            await AfterInitAsync();
 3771        }
 172        catch (Exception ex)
 73        {
 174            _logger.LogError($"Failed to initialize settings for {_storageKey}: {ex.Message}");
 175        }
 76        finally
 77        {
 3878            _isInitializing = false;
 79        }
 3880    }
 81
 82    /// <summary>
 83    /// Вызывается сразу после загрузки настроек
 84    /// Сюда надо добавлять первичные манипуляции с настройками
 85    /// </summary>
 086    protected virtual Task AfterInitAsync() => Task.CompletedTask;
 87
 88    private void CopyProperties(TOptions from, TOptions to)
 89    {
 990        var properties = typeof(TOptions).GetProperties(BindingFlags.Public | BindingFlags.Instance)
 2791            .Where(p => p is { CanRead: true, CanWrite: true });
 92
 5493        foreach (var prop in properties)
 94        {
 1895            var value = prop.GetValue(from);
 1896            prop.SetValue(to, value);
 97        }
 998    }
 99
 100    public abstract Task ResetAsync();
 101
 102    public virtual void Dispose()
 103    {
 0104        Current.PropertyChanged -= OnPropertyChanged;
 0105        Debouncer.Dispose();
 0106    }
 107}