diff --git a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj index 1475252ca..84b603161 100644 --- a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj +++ b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj @@ -54,6 +54,7 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs index 7d7235968..8eaa757be 100644 --- a/Flow.Launcher.Infrastructure/PinyinAlphabet.cs +++ b/Flow.Launcher.Infrastructure/PinyinAlphabet.cs @@ -6,6 +6,7 @@ using System.Text; using JetBrains.Annotations; using Flow.Launcher.Infrastructure.UserSettings; using ToolGood.Words.Pinyin; +using CommunityToolkit.Mvvm.DependencyInjection; namespace Flow.Launcher.Infrastructure { @@ -129,7 +130,12 @@ namespace Flow.Launcher.Infrastructure private Settings _settings; - public void Initialize([NotNull] Settings settings) + public PinyinAlphabet() + { + Initialize(Ioc.Default.GetRequiredService()); + } + + private void Initialize([NotNull] Settings settings) { _settings = settings ?? throw new ArgumentNullException(nameof(settings)); } diff --git a/Flow.Launcher.Infrastructure/StringMatcher.cs b/Flow.Launcher.Infrastructure/StringMatcher.cs index bd5dbdda9..7134fc760 100644 --- a/Flow.Launcher.Infrastructure/StringMatcher.cs +++ b/Flow.Launcher.Infrastructure/StringMatcher.cs @@ -1,4 +1,5 @@ -using Flow.Launcher.Plugin.SharedModels; +using CommunityToolkit.Mvvm.DependencyInjection; +using Flow.Launcher.Plugin.SharedModels; using System; using System.Collections.Generic; using System.Linq; @@ -15,7 +16,7 @@ namespace Flow.Launcher.Infrastructure public StringMatcher(IAlphabet alphabet = null) { - _alphabet = alphabet; + _alphabet = Ioc.Default.GetRequiredService(); } public static StringMatcher Instance { get; internal set; } diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs index 9d7a0671e..8cd054148 100644 --- a/Flow.Launcher/App.xaml.cs +++ b/Flow.Launcher/App.xaml.cs @@ -4,6 +4,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; +using CommunityToolkit.Mvvm.DependencyInjection; using Flow.Launcher.Core; using Flow.Launcher.Core.Configuration; using Flow.Launcher.Core.ExternalPlugins.Environments; @@ -18,23 +19,18 @@ using Flow.Launcher.Infrastructure.Storage; using Flow.Launcher.Infrastructure.UserSettings; using Flow.Launcher.Plugin; using Flow.Launcher.ViewModel; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch; namespace Flow.Launcher { - public partial class App : IDisposable, ISingleInstanceApp, IApp + public partial class App : IDisposable, ISingleInstanceApp { - public IPublicAPI PublicAPI => API; public static PublicAPIInstance API { get; private set; } private const string Unique = "Flow.Launcher_Unique_Application_Mutex"; private static bool _disposed; private Settings _settings; - private MainViewModel _mainVM; - private SettingWindowViewModel _settingsVM; - private readonly Updater _updater = new Updater(Flow.Launcher.Properties.Settings.Default.GithubRepo); - private readonly Portable _portable = new Portable(); - private readonly PinyinAlphabet _alphabet = new PinyinAlphabet(); - private StringMatcher _stringMatcher; [STAThread] public static void Main() @@ -53,37 +49,51 @@ namespace Flow.Launcher { await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () => { + // Initialize settings var storage = new FlowLauncherJsonStorage(); _settings = storage.Load(); _settings.Initialize(storage); + _settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled(); - _portable.PreStartCleanUpAfterPortabilityUpdate(); + // Configure the dependency injection container + var host = Host.CreateDefaultBuilder() + .UseContentRoot(AppContext.BaseDirectory) + .ConfigureServices(services => services + .AddSingleton(_ => _settings) + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + ).Build(); + Ioc.Default.ConfigureServices(host.Services); - Log.Info( - "|App.OnStartup|Begin Flow Launcher startup ----------------------------------------------------"); + Ioc.Default.GetRequiredService().Initialize(Launcher.Properties.Settings.Default.GithubRepo); + + Ioc.Default.GetRequiredService().PreStartCleanUpAfterPortabilityUpdate(); + + Log.Info("|App.OnStartup|Begin Flow Launcher startup ----------------------------------------------------"); Log.Info($"|App.OnStartup|Runtime info:{ErrorReporting.RuntimeInfo()}"); + RegisterAppDomainExceptions(); RegisterDispatcherUnhandledException(); var imageLoadertask = ImageLoader.InitializeAsync(); - _settingsVM = new SettingWindowViewModel(_settings, _updater, _portable); - _settings.WMPInstalled = WindowsMediaPlayerHelper.IsWindowsMediaPlayerInstalled(); - AbstractPluginEnvironment.PreStartPluginExecutablePathUpdate(_settings); - _alphabet.Initialize(_settings); - _stringMatcher = new StringMatcher(_alphabet); - StringMatcher.Instance = _stringMatcher; - _stringMatcher.UserSettingSearchPrecision = _settings.QuerySearchPrecision; + var stringMatcher = Ioc.Default.GetRequiredService(); + StringMatcher.Instance = stringMatcher; + stringMatcher.UserSettingSearchPrecision = _settings.QuerySearchPrecision; InternationalizationManager.Instance.Settings = _settings; InternationalizationManager.Instance.ChangeLanguage(_settings.Language); PluginManager.LoadPlugins(_settings.PluginSettings); - _mainVM = new MainViewModel(_settings); - API = new PublicAPIInstance(_settingsVM, _mainVM, _alphabet); + API = Ioc.Default.GetRequiredService() as PublicAPIInstance; Http.API = API; Http.Proxy = _settings.Proxy; @@ -91,14 +101,15 @@ namespace Flow.Launcher await PluginManager.InitializePluginsAsync(API); await imageLoadertask; - var window = new MainWindow(_settings, _mainVM); + var mainVM = Ioc.Default.GetRequiredService(); + var window = new MainWindow(_settings, mainVM); Log.Info($"|App.OnStartup|Dependencies Info:{ErrorReporting.DependenciesInfo()}"); Current.MainWindow = window; Current.MainWindow.Title = Constant.FlowLauncher; - HotKeyMapper.Initialize(_mainVM); + HotKeyMapper.Initialize(mainVM); // main windows needs initialized before theme change because of blur settings ThemeManager.Instance.Settings = _settings; @@ -147,11 +158,11 @@ namespace Flow.Launcher { // check update every 5 hours var timer = new PeriodicTimer(TimeSpan.FromHours(5)); - await _updater.UpdateAppAsync(API); + await Ioc.Default.GetRequiredService().UpdateAppAsync(API); while (await timer.WaitForNextTickAsync()) // check updates on startup - await _updater.UpdateAppAsync(API); + await Ioc.Default.GetRequiredService().UpdateAppAsync(API); } }); } @@ -194,7 +205,7 @@ namespace Flow.Launcher public void OnSecondAppStarted() { - _mainVM.Show(); + Ioc.Default.GetRequiredService().Show(); } } } diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj index 4ec249c2b..cab3915d5 100644 --- a/Flow.Launcher/Flow.Launcher.csproj +++ b/Flow.Launcher/Flow.Launcher.csproj @@ -1,4 +1,4 @@ - + WinExe @@ -83,12 +83,13 @@ - all runtime; build; native; contentfiles; analyzers; buildtransitive + + all diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs index f0295cf24..50765294c 100644 --- a/Flow.Launcher/PublicAPIInstance.cs +++ b/Flow.Launcher/PublicAPIInstance.cs @@ -25,7 +25,7 @@ using Flow.Launcher.Infrastructure.Storage; using System.Collections.Concurrent; using System.Diagnostics; using System.Collections.Specialized; -using Flow.Launcher.Core; +using CommunityToolkit.Mvvm.DependencyInjection; namespace Flow.Launcher { @@ -33,15 +33,15 @@ namespace Flow.Launcher { private readonly SettingWindowViewModel _settingsVM; private readonly MainViewModel _mainVM; - private readonly PinyinAlphabet _alphabet; + private readonly IAlphabet _alphabet; #region Constructor - public PublicAPIInstance(SettingWindowViewModel settingsVM, MainViewModel mainVM, PinyinAlphabet alphabet) + public PublicAPIInstance() { - _settingsVM = settingsVM; - _mainVM = mainVM; - _alphabet = alphabet; + _settingsVM = Ioc.Default.GetRequiredService(); + _mainVM = Ioc.Default.GetRequiredService(); + _alphabet = Ioc.Default.GetRequiredService(); GlobalHotkey.hookedKeyboardCallback = KListener_hookedKeyboardCallback; WebRequest.RegisterPrefix("data", new DataWebRequestFactory()); } diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index 55bc8d1b3..f5141a8fa 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -25,6 +25,7 @@ using System.Windows.Input; using System.ComponentModel; using Flow.Launcher.Infrastructure.Image; using System.Windows.Media; +using CommunityToolkit.Mvvm.DependencyInjection; namespace Flow.Launcher.ViewModel { @@ -58,13 +59,13 @@ namespace Flow.Launcher.ViewModel #region Constructor - public MainViewModel(Settings settings) + public MainViewModel() { _queryTextBeforeLeaveResults = ""; _queryText = ""; _lastQuery = new Query(); - Settings = settings; + Settings = Ioc.Default.GetRequiredService(); Settings.PropertyChanged += (_, args) => { switch (args.PropertyName) diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs index 95a1eb675..7549db1a3 100644 --- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs +++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs @@ -1,4 +1,5 @@ -using Flow.Launcher.Core; +using CommunityToolkit.Mvvm.DependencyInjection; +using Flow.Launcher.Core; using Flow.Launcher.Core.Configuration; using Flow.Launcher.Infrastructure.UserSettings; using Flow.Launcher.Plugin; @@ -13,11 +14,11 @@ public class SettingWindowViewModel : BaseModel public Settings Settings { get; } - public SettingWindowViewModel(Settings settings, Updater updater, IPortable portable) + public SettingWindowViewModel() { - Settings = settings; - Updater = updater; - Portable = portable; + Settings = Ioc.Default.GetRequiredService(); + Updater = Ioc.Default.GetRequiredService(); + Portable = Ioc.Default.GetRequiredService(); } public async void UpdateApp()