using System.Collections.Concurrent; using WindowsGotify.Models; namespace WindowsGotify.Services; /// /// 缓存 Gotify Applications 列表(从 GET /application 拉取),供 UI 用来把消息的 AppId 解析为可读应用名。 /// public sealed class ApplicationCache { private readonly ConcurrentDictionary _apps = new(); private readonly GotifyApiService _api; private readonly Logger _logger; private DateTimeOffset _lastFetchedAt = DateTimeOffset.MinValue; public ApplicationCache(GotifyApiService api, Logger logger) { _api = api; _logger = logger; } public int Count => _apps.Count; public event EventHandler? Updated; /// /// 拉一次最新的应用列表。失败抛异常,调用方决定怎么处理(忽略 / 重试 / 提示)。 /// public async Task RefreshAsync(CancellationToken ct = default) { var list = await _api.GetApplicationsAsync(ct); _apps.Clear(); foreach (var app in list) { _apps[app.Id] = app; } _lastFetchedAt = DateTimeOffset.UtcNow; _logger.Info($"ApplicationCache refreshed. count={list.Count}"); Updated?.Invoke(this, EventArgs.Empty); } /// /// 把 appId 解析为应用名。缓存里没有就回退 "App {id}"。 /// public string GetName(long appId) { return _apps.TryGetValue(appId, out var app) && !string.IsNullOrWhiteSpace(app.Name) ? app.Name : $"App {appId}"; } public GotifyApplication? Get(long appId) { _apps.TryGetValue(appId, out var app); return app; } public DateTimeOffset LastFetchedAt => _lastFetchedAt; }