From 5148280c36ad2e16ec29cf445dca97ff844b682f Mon Sep 17 00:00:00 2001 From: Daniel Pichler Date: Fri, 26 Dec 2025 17:04:52 +0100 Subject: [PATCH] Refactor: Remove `ITokenProvider` and `SettingsTokenProvider`; update StundePage layout and optimize dependency injection configuration. --- .../Infrastructure/ApiClient.cs | 2 +- .../Infrastructure/SettingsTokenProvider.cs | 10 - .../Interfaces/ITokenProvider.cs | 5 - Jugenddienst Stunden/MauiProgram.cs | 65 +------ .../ViewModels/StundeViewModel.cs | 2 + .../ViewModels/StundenViewModel.cs | 1 - Jugenddienst Stunden/Views/StundePage.xaml | 178 ++++++++++-------- Jugenddienst Stunden/Views/StundePage.xaml.cs | 8 - 8 files changed, 113 insertions(+), 158 deletions(-) delete mode 100644 Jugenddienst Stunden/Infrastructure/SettingsTokenProvider.cs delete mode 100644 Jugenddienst Stunden/Interfaces/ITokenProvider.cs diff --git a/Jugenddienst Stunden/Infrastructure/ApiClient.cs b/Jugenddienst Stunden/Infrastructure/ApiClient.cs index 729965c..c56375b 100644 --- a/Jugenddienst Stunden/Infrastructure/ApiClient.cs +++ b/Jugenddienst Stunden/Infrastructure/ApiClient.cs @@ -13,7 +13,7 @@ internal sealed class ApiClient : IApiClient { private readonly ApiOptions _options; private readonly IAppSettings _settings; - public ApiClient(HttpClient http, ApiOptions options, ITokenProvider tokenProvider, IAppSettings settings) { + public ApiClient(HttpClient http, ApiOptions options, IAppSettings settings) { _http = http; _options = options; _settings = settings; diff --git a/Jugenddienst Stunden/Infrastructure/SettingsTokenProvider.cs b/Jugenddienst Stunden/Infrastructure/SettingsTokenProvider.cs deleted file mode 100644 index 2b2bbe9..0000000 --- a/Jugenddienst Stunden/Infrastructure/SettingsTokenProvider.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Jugenddienst_Stunden.Interfaces; - -namespace Jugenddienst_Stunden.Infrastructure; - -internal sealed class SettingsTokenProvider : ITokenProvider { - private readonly IAppSettings _settings; - public SettingsTokenProvider(IAppSettings settings) => _settings = settings; - - public string GetToken() => _settings.ApiKey; -} \ No newline at end of file diff --git a/Jugenddienst Stunden/Interfaces/ITokenProvider.cs b/Jugenddienst Stunden/Interfaces/ITokenProvider.cs deleted file mode 100644 index 81fbe88..0000000 --- a/Jugenddienst Stunden/Interfaces/ITokenProvider.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace Jugenddienst_Stunden.Interfaces; - -internal interface ITokenProvider { - string? GetToken(); -} \ No newline at end of file diff --git a/Jugenddienst Stunden/MauiProgram.cs b/Jugenddienst Stunden/MauiProgram.cs index f1b73de..20d93b5 100644 --- a/Jugenddienst Stunden/MauiProgram.cs +++ b/Jugenddienst Stunden/MauiProgram.cs @@ -28,26 +28,8 @@ public static class MauiProgram { fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); }) - //.UseBarcodeScanning(); .UseBarcodeReader(); - //#if DEBUG - // if (string.IsNullOrWhiteSpace(GlobalVar.ApiKey)) { - // GlobalVar.ApiKey = Preferences.Default.Get("apiKey", - // "MTQxfHNkdFptQkNZTXlPT3ZyMHxodHRwOi8vaG91cnMuZGF1bmkubWluZS5udTo4MS9hcHBhcGk="); - // GlobalVar.Name = Preferences.Default.Get("name", "Testserver: Isabell"); - // GlobalVar.Surname = Preferences.Default.Get("surname", "Biasi"); - // GlobalVar.EmployeeId = Preferences.Default.Get("EmployeeId", 141); - // GlobalVar.ApiUrl = Preferences.Default.Get("apiUrl", "https://hours.dauni.mine.nu/appapi"); - // } - - // builder.Logging.AddDebug(); - //#endif - - // ApiClient registrieren: SocketsHttpHandler als Primary Handler (vermeidet AndroidMessageHandler-Castfehler) - //var apiOptions = new Infrastructure.ApiOptions { BaseUrl = GlobalVar.ApiUrl, Timeout = TimeSpan.FromSeconds(15) }; - //builder.Services.AddApiHttpClient(apiOptions); - // DI: AlertService für globale Alerts (z. B. leere ApiUrl) builder.Services.AddSingleton(); @@ -60,49 +42,22 @@ public static class MauiProgram { Timeout = TimeSpan.FromSeconds(15) }); - // Token Provider soll ebenfalls aus Settings/Preferences lesen - builder.Services.AddSingleton(); - // HttpClient + ApiClient - // Configure HttpClient with SocketsHttpHandler (managed) and RequestLoggingHandler + // HttpClient + ApiClient Best Practices: + // 1. IHttpClientFactory verwenden (vermeidet Socket Exhaustion & DNS Probleme) + // 2. Typed Client für bessere Dependency Injection (AddHttpClient) + // 3. DelegatingHandler für Logging/Infrastruktur einbinden builder.Services.AddTransient(); - builder.Services.AddSingleton(sp => { - var nativeHandler = new SocketsHttpHandler { + + builder.Services.AddHttpClient() + .ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler { AllowAutoRedirect = false, AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate, PooledConnectionLifetime = TimeSpan.FromMinutes(5), ConnectTimeout = TimeSpan.FromSeconds(10) - }; - var logging = sp.GetRequiredService(); - logging.InnerHandler = nativeHandler; - // HttpClient.Timeout will be adjusted by ApiClient if needed - return new HttpClient(logging, disposeHandler: true); - }); - - builder.Services.AddSingleton(sp => { - var alert = sp.GetRequiredService(); - try { - return new ApiClient( - sp.GetRequiredService(), - sp.GetRequiredService(), - sp.GetRequiredService(), - sp.GetRequiredService()); - } catch (Exception e) { - // Alert an UI/VM weiterreichen - alert.Raise(e.Message); - // Fallback: NullApiClient liefert beim Aufruf aussagekräftige Exception - return new NullApiClient(e.Message); - } - }); - - // DI: Infrastruktur - //builder.Services.AddSingleton(new ApiOptions { BaseUrl = GlobalVar.ApiUrl, Timeout = TimeSpan.FromSeconds(15) }); - //builder.Services.AddSingleton(); - //builder.Services.AddSingleton(_ => new HttpClient()); - //builder.Services.AddSingleton(sp => new ApiClient( - // sp.GetRequiredService(), - // sp.GetRequiredService(), - // sp.GetRequiredService())); + }) + .AddHttpMessageHandler() + .SetHandlerLifetime(TimeSpan.FromMinutes(5)); // DI: Validatoren builder.Services.AddSingleton(); diff --git a/Jugenddienst Stunden/ViewModels/StundeViewModel.cs b/Jugenddienst Stunden/ViewModels/StundeViewModel.cs index d700831..440fd9d 100644 --- a/Jugenddienst Stunden/ViewModels/StundeViewModel.cs +++ b/Jugenddienst Stunden/ViewModels/StundeViewModel.cs @@ -233,6 +233,8 @@ public partial class StundeViewModel : ObservableObject, IQueryAttributable { //die soll aber ignoriert werden, weil beim Neueintrag ist das ja Wurscht //In dem Fall müssen die Settings aber nochmal geholt werden, weil die dann nicht geladen wurden // LoadSettingsAsync(); + var settings = await _hoursService.GetSettingsAsync(); + UpdateSettings(settings); } finally { DayTime = new DayTime(); DayTime.Day = _date; diff --git a/Jugenddienst Stunden/ViewModels/StundenViewModel.cs b/Jugenddienst Stunden/ViewModels/StundenViewModel.cs index 7d41cdf..320121c 100644 --- a/Jugenddienst Stunden/ViewModels/StundenViewModel.cs +++ b/Jugenddienst Stunden/ViewModels/StundenViewModel.cs @@ -231,7 +231,6 @@ public partial class StundenViewModel : ObservableObject, IQueryAttributable, IN " installiert)"); } - //_hour = await HoursBase.LoadData(); RefreshProperties(); } catch (Exception e) { AlertEvent?.Invoke(this, e.Message); diff --git a/Jugenddienst Stunden/Views/StundePage.xaml b/Jugenddienst Stunden/Views/StundePage.xaml index 7c80d50..4823833 100644 --- a/Jugenddienst Stunden/Views/StundePage.xaml +++ b/Jugenddienst Stunden/Views/StundePage.xaml @@ -21,64 +21,81 @@ StatusBarStyle="LightContent" /> - + + + + + + + + + + -