< Summary

Information
Class: UIBlazor.Services.Settings.BaseSettingsProvider<T>
Assembly: UIBlazor
File(s): /home/runner/work/InvAit/InvAit/UIBlazor/Services/Settings/BaseSettingsProvider.cs
Tag: 14_22728831704
Line coverage
87%
Covered lines: 36
Uncovered lines: 5
Coverable lines: 41
Total lines: 112
Line coverage: 87.8%
Branch coverage
75%
Covered branches: 12
Total branches: 16
Branch coverage: 75%
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%
OnAnyPropertyChanged(...)100%210%
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    protected readonly ILocalStorageService Storage;
 9    protected readonly string StorageKey;
 10    protected readonly Debouncer Debouncer;
 11    private bool _isInitializing;
 12    private readonly ILogger _logger;
 13
 12614    public TOptions Current { get; } = new();
 15
 2316    protected BaseSettingsProvider(
 2317        ILocalStorageService storage,
 2318        ILogger logger,
 2319        string storageKey,
 2320        TimeSpan? debounceDelay = null)
 21    {
 2322        Storage = storage;
 2323        _logger = logger;
 2324        StorageKey = storageKey;
 2325        Debouncer = new Debouncer(debounceDelay ?? TimeSpan.FromMilliseconds(750), SaveAsync);
 2326    }
 27
 28    private void OnPropertyChanged(object? sender, PropertyChangedEventArgs e)
 29    {
 330        if (!_isInitializing)
 31        {
 132            OnAnyPropertyChanged(e.PropertyName);
 133            Debouncer.Trigger();
 34        }
 335    }
 36
 37    /// <summary>
 38    /// Свойство изменилось и будет сохранено
 39    /// </summary>
 40    /// <param name="propertyName">Имя измененного свойства</param>
 41    protected virtual void OnAnyPropertyChanged(string? propertyName)
 42    {
 043    }
 44
 45    /// <summary>
 46    /// Событие после сохранения настроек
 47    /// </summary>
 48    public event Action? OnSaved;
 49
 50    /// <summary>
 51    /// Немедленное сохранение Current объекта.<br/>
 52    /// Автоматически вызывается при изменении любого свойства, которое использует <see cref="BaseOptions.SetIfChanged"/
 53    /// </summary>
 54    public virtual async Task SaveAsync()
 55    {
 956        await Storage.SetItemAsync(StorageKey, Current);
 957        OnSaved?.Invoke();
 958    }
 59
 60    /// <summary>
 61    /// Загрузка настроек
 62    /// </summary>
 63    public async Task InitializeAsync()
 64    {
 1365        _isInitializing = true;
 66        try
 67        {
 1368            var saved = await Storage.GetItemAsync<TOptions>(StorageKey);
 1269            if (saved != null)
 70            {
 571                CopyProperties(saved, Current);
 72            }
 73
 1274            Current.PropertyChanged += OnPropertyChanged;
 1275            await AfterInitAsync();
 1276        }
 177        catch (Exception ex)
 78        {
 179            _logger.LogError($"Failed to initialize settings for {StorageKey}: {ex.Message}");
 180        }
 81        finally
 82        {
 1383            _isInitializing = false;
 84        }
 1385    }
 86
 87    /// <summary>
 88    /// Вызывается сразу после загрузки настроек
 89    /// Сюда надо добавлять первичные манипуляции с настройками
 90    /// </summary>
 091    protected virtual Task AfterInitAsync() => Task.CompletedTask;
 92
 93    protected virtual void CopyProperties(TOptions from, TOptions to)
 94    {
 595        var properties = typeof(TOptions).GetProperties(BindingFlags.Public | BindingFlags.Instance)
 1596            .Where(p => p is { CanRead: true, CanWrite: true });
 97
 3098        foreach (var prop in properties)
 99        {
 10100            var value = prop.GetValue(from);
 10101            prop.SetValue(to, value);
 102        }
 5103    }
 104
 105    public abstract Task ResetAsync();
 106
 107    public virtual void Dispose()
 108    {
 0109        Current.PropertyChanged -= OnPropertyChanged;
 0110        Debouncer.Dispose();
 0111    }
 112}