using Avalonia; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Input.Platform; using Avalonia.Markup.Xaml; using JdeScoping.ConfigManager.Core.DependencyInjection; using JdeScoping.ConfigManager.Ui.Services; using JdeScoping.ConfigManager.Ui.ViewModels; using Microsoft.Extensions.DependencyInjection; using Serilog; using Serilog.Events; namespace JdeScoping.ConfigManager.Ui; public partial class App : Avalonia.Application { /// /// Gets the dependency injection service provider for the application. /// public static IServiceProvider Services { get; private set; } = null!; /// public override void Initialize() { AvaloniaXamlLoader.Load(this); } /// public override void OnFrameworkInitializationCompleted() { var services = new ServiceCollection(); ConfigureServices(services); Services = services.BuildServiceProvider(); if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { desktop.MainWindow = new Views.MainWindow { DataContext = Services.GetRequiredService() }; // Ensure logs are flushed on exit desktop.ShutdownRequested += (_, _) => Log.CloseAndFlush(); } base.OnFrameworkInitializationCompleted(); } private void ConfigureServices(IServiceCollection services) { // Configure Serilog with daily rolling file var logsPath = Path.Combine(AppContext.BaseDirectory, "logs"); Directory.CreateDirectory(logsPath); Log.Logger = new LoggerConfiguration() .MinimumLevel.Information() .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) .MinimumLevel.Override("Avalonia", LogEventLevel.Warning) .Enrich.FromLogContext() .WriteTo.File( path: Path.Combine(logsPath, "configmanager-.log"), rollingInterval: RollingInterval.Day, retainedFileCountLimit: 30, outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}") .CreateLogger(); // Logging services.AddLogging(builder => builder.AddSerilog(dispose: true)); // Add all ConfigManager.Core services services.AddConfigManagerCore(); // Platform Services (Avalonia-specific) services.AddSingleton(sp => new AvaloniaDialogService(GetMainWindow)); services.AddSingleton(sp => new AvaloniaClipboardService(GetClipboard)); // ViewModels services.AddTransient(); } private Window? GetMainWindow() { return (ApplicationLifetime as IClassicDesktopStyleApplicationLifetime)?.MainWindow; } private IClipboard? GetClipboard() { return GetMainWindow()?.Clipboard; } }