From 6b835b1895c95ffeedece8272377271e928cc97f Mon Sep 17 00:00:00 2001 From: Jahn Spohrer <73436710+jahnspohrer@users.noreply.github.com> Date: Thu, 5 Sep 2024 16:09:05 +0200 Subject: [PATCH] reworked start up --- App.axaml.cs | 46 +++++++++++++++++------------ Extensions/DataContextExtensions.cs | 21 ------------- Misc/Tools.cs | 12 +++----- ViewModels/MainWindowViewModel.cs | 24 ++++++++------- 4 files changed, 44 insertions(+), 59 deletions(-) delete mode 100644 Extensions/DataContextExtensions.cs diff --git a/App.axaml.cs b/App.axaml.cs index 4817aa7..eb9c4e2 100644 --- a/App.axaml.cs +++ b/App.axaml.cs @@ -1,8 +1,10 @@ using System; +using System.Diagnostics; using Avalonia; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Data.Core.Plugins; using Avalonia.Markup.Xaml; +using Avalonia.Threading; using BetterRaid.Extensions; using BetterRaid.Services; using BetterRaid.Services.Implementations; @@ -14,46 +16,52 @@ namespace BetterRaid; public class App : Application { - private static readonly ServiceCollection Services = []; - private static ServiceProvider? _serviceProvider; - - public static IServiceProvider? ServiceProvider => _serviceProvider; + private ServiceProvider? _serviceProvider; public override void Initialize() { - InitializeServices(); - + _serviceProvider = InitializeServices(); AvaloniaXamlLoader.Load(_serviceProvider, this); } - private void InitializeServices() + private ServiceProvider InitializeServices() { + var Services = new ServiceCollection(); Services.AddSingleton(); Services.AddSingleton(); - Services.AddTransient(); - - _serviceProvider = Services.BuildServiceProvider(); + Services.AddSingleton(serviceProvider => new DispatcherService(Dispatcher.UIThread)); + Services.AddTransient(); + + return Services.BuildServiceProvider(); } public override void OnFrameworkInitializationCompleted() { BindingPlugins.DataValidators.RemoveAt(0); - + + if(_serviceProvider == null) + { + throw new FieldAccessException($"\"{nameof(_serviceProvider)}\" was null"); + } + + var viewModelFactory = _serviceProvider.GetRequiredService(); + var mainWindowViewModel = viewModelFactory.CreateMainWindowViewModel(); + var mainWindow = new MainWindow() + { + DataContext = mainWindowViewModel + }; + switch (ApplicationLifetime) { case IClassicDesktopStyleApplicationLifetime desktop: - desktop.MainWindow = new MainWindow(); - desktop.MainWindow.InjectDataContext(); - + desktop.MainWindow = mainWindow; break; - + case ISingleViewApplicationLifetime singleViewPlatform: - singleViewPlatform.MainView = new MainWindow(); - singleViewPlatform.MainView.InjectDataContext(); - + singleViewPlatform.MainView = mainWindow; break; } - + base.OnFrameworkInitializationCompleted(); } } \ No newline at end of file diff --git a/Extensions/DataContextExtensions.cs b/Extensions/DataContextExtensions.cs deleted file mode 100644 index 527528d..0000000 --- a/Extensions/DataContextExtensions.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Avalonia; -using Microsoft.Extensions.DependencyInjection; - -namespace BetterRaid.Extensions; - -public static class DataContextExtensions -{ - public static T? GetDataContextAs(this T obj) where T : StyledElement - { - return obj.DataContext as T; - } - - public static void InjectDataContext(this StyledElement e) where T : class - { - if (App.ServiceProvider == null) - return; - - var vm = App.ServiceProvider.GetRequiredService(); - e.DataContext = vm; - } -} \ No newline at end of file diff --git a/Misc/Tools.cs b/Misc/Tools.cs index f92bdc5..453ec39 100644 --- a/Misc/Tools.cs +++ b/Misc/Tools.cs @@ -15,7 +15,7 @@ public static class Tools private static HttpListener? _oauthListener; // Source: https://stackoverflow.com/a/43232486 - public static void StartOAuthLogin(string url, Action? callback = null, CancellationToken token = default) + public static void StartOAuthLogin(string url, ITwitchDataService twitchDataService, Action? callback = null, CancellationToken token = default) { if (_oauthListener == null) { @@ -23,13 +23,13 @@ public static class Tools _oauthListener.Prefixes.Add(Constants.TwitchOAuthRedirectUrl + "/"); _oauthListener.Start(); - Task.Run(() => WaitForCallback(callback, token), token); + Task.Run(() => WaitForCallback(callback, token, twitchDataService), token); } OpenUrl(url); } - private static async Task WaitForCallback(Action? callback, CancellationToken token) + private static async Task WaitForCallback(Action? callback, CancellationToken token, ITwitchDataService twitchDataService) { if (_oauthListener == null) return; @@ -107,11 +107,7 @@ public static class Tools var accessToken = jsonData["access_token"]?.ToString(); - var dataService = App.ServiceProvider?.GetService(typeof(ITwitchDataService)); - if (dataService is ITwitchDataService twitchDataService) - { - twitchDataService.ConnectApiAsync(Constants.TwitchClientId, accessToken!); - } + twitchDataService.ConnectApiAsync(Constants.TwitchClientId, accessToken!); res.StatusCode = 200; res.Close(); diff --git a/ViewModels/MainWindowViewModel.cs b/ViewModels/MainWindowViewModel.cs index 57a1c19..d829ea3 100644 --- a/ViewModels/MainWindowViewModel.cs +++ b/ViewModels/MainWindowViewModel.cs @@ -19,6 +19,7 @@ public class MainWindowViewModel : ViewModelBase private ObservableCollection _channels = []; private readonly BetterRaidDatabase? _db; private readonly ITwitchPubSubService _pubSub; + private readonly ISynchronizaionService _synchronizaionService; public BetterRaidDatabase? Database { @@ -37,7 +38,7 @@ public class MainWindowViewModel : ViewModelBase get => _channels; set => SetProperty(ref _channels, value); } - + public ObservableCollection FilteredChannels => GetFilteredChannels(); public ITwitchDataService DataService { get; } @@ -50,10 +51,11 @@ public class MainWindowViewModel : ViewModelBase public bool IsLoggedIn => DataService.UserChannel != null; - public MainWindowViewModel(ITwitchPubSubService pubSub, ITwitchDataService dataService) + public MainWindowViewModel(ITwitchPubSubService pubSub, ITwitchDataService dataService, ISynchronizaionService synchronizaionService) { _pubSub = pubSub; DataService = dataService; + _synchronizaionService = synchronizaionService; DataService.PropertyChanged += OnDataServicePropertyChanged; Database = BetterRaidDatabase.LoadFromFile(Constants.DatabaseFilePath); @@ -75,7 +77,7 @@ public class MainWindowViewModel : ViewModelBase public void LoginWithTwitch() { - Tools.StartOAuthLogin(DataService.GetOAuthUrl(), OnTwitchLoginCallback, CancellationToken.None); + Tools.StartOAuthLogin(DataService.GetOAuthUrl(), DataService, OnTwitchLoginCallback, CancellationToken.None); } private void OnTwitchLoginCallback() @@ -89,18 +91,18 @@ public class MainWindowViewModel : ViewModelBase { return; } - + foreach (var channel in Channels) { _pubSub.UnregisterReceiver(channel); } - + Channels.Clear(); var channels = _db.Channels .Select(channelName => new TwitchChannel(channelName)) .ToList(); - + foreach (var channel in channels) { Task.Run(() => @@ -108,7 +110,7 @@ public class MainWindowViewModel : ViewModelBase channel.UpdateChannelData(DataService); _pubSub.RegisterReceiver(channel); }); - + Channels.Add(channel); } } @@ -119,7 +121,7 @@ public class MainWindowViewModel : ViewModelBase .Where(channel => Database?.OnlyOnline == false || channel.IsLive) .Where(channel => string.IsNullOrWhiteSpace(Filter) || channel.Name?.Contains(Filter, StringComparison.OrdinalIgnoreCase) == true) .ToList(); - + return new ObservableCollection(filteredChannels); } @@ -127,14 +129,14 @@ public class MainWindowViewModel : ViewModelBase { if (e.PropertyName != nameof(DataService.UserChannel)) return; - + OnPropertyChanged(nameof(IsLoggedIn)); } protected override void OnPropertyChanged(PropertyChangedEventArgs e) { base.OnPropertyChanged(e); - + if (e.PropertyName == nameof(Filter)) { OnPropertyChanged(nameof(FilteredChannels)); @@ -145,7 +147,7 @@ public class MainWindowViewModel : ViewModelBase { if (e.PropertyName != nameof(BetterRaidDatabase.OnlyOnline)) return; - + OnPropertyChanged(nameof(FilteredChannels)); } }