Invert composition root to DI container

Build the Microsoft.Extensions.DependencyInjection provider in App and resolve the view model and runtime factory from it, replacing the manual new MainWindow(trace) path. MainWindow now takes an injected ctor (view model, tracer, runtime factory, provider); window-tied services are produced by MainWindowRuntimeFactory once the window exists. On real shutdown MainWindow_Closed disposes the provider (which disposes the view model first, then domain services and tracer), while the minimize-to-tray branch returns before any teardown.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-06-02 15:16:28 -05:00
co-authored by Copilot
parent 594429bb7d
commit 3e71e09a25
4 changed files with 184 additions and 29 deletions
+11 -1
View File
@@ -5,7 +5,10 @@
using System;
using System.IO;
using System.Threading.Tasks;
using LibreHardwareMonitor.Windows.WinUI.Composition;
using LibreHardwareMonitor.Windows.WinUI.Services.Tracing;
using LibreHardwareMonitor.Windows.WinUI.ViewModels;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.UI.Xaml;
using IOPath = System.IO.Path;
@@ -15,6 +18,7 @@ public partial class App : Application
{
private bool _launchStarted;
private readonly IStartupTracer _startupTrace;
private ServiceProvider? _serviceProvider;
private Window? _window;
public App()
@@ -46,7 +50,13 @@ public partial class App : Application
try
{
_startupTrace.Mark("App.LaunchMainWindow.Begin");
MainWindow mainWindow = MeasureStartup("App.CreateMainWindow", () => new MainWindow(_startupTrace));
_serviceProvider = MeasureStartup("App.BuildServiceProvider", () =>
new ServiceCollection().AddAppServices(_startupTrace).BuildServiceProvider());
MainWindow mainWindow = MeasureStartup("App.CreateMainWindow", () => new MainWindow(
_serviceProvider.GetRequiredService<MainWindowViewModel>(),
_startupTrace,
_serviceProvider.GetRequiredService<IMainWindowRuntimeFactory>(),
_serviceProvider));
_window = mainWindow;
MeasureStartup("App.ActivateWindow", mainWindow.Activate);
MeasureStartup("App.StartMonitoringAfterActivation", mainWindow.StartMonitoringAfterActivation);