using Avalonia; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Data.Core.Plugins; using Avalonia.Markup.Xaml; using AvaloniaLoggingDI.ViewModels; using AvaloniaLoggingDI.Views; using LogViewer.Avalonia; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using MsBox.Avalonia; using MsBox.Avalonia.Enums; using MsLogger.Core; using RandomLogging.Service; using System; using System.Drawing; using System.Linq; using System.Reflection; using System.Threading; using Icon = MsBox.Avalonia.Enums.Icon; namespace AvaloniaLoggingDI; public partial class App : Application { public override void Initialize() => AvaloniaXamlLoader.Load(this); public override void OnFrameworkInitializationCompleted() { if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { // Avoid duplicate validations from both Avalonia and the CommunityToolkit. // More info: https://docs.avaloniaui.net/docs/guides/development-guides/data-validation#manage-validationplugins DisableAvaloniaDataAnnotationValidation(); // catch all unhandled errors AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; HostApplicationBuilder builder = Host.CreateApplicationBuilder(); builder /* * Note: For information on launch profiles for debugging, * see article: https://www.codeproject.com/Articles/5354478/NET-App-Settings-Demystified-Csharp-VB */ // Register the Random Logging Service .AddRandomBackgroundService() // visual debugging tools .AddLogViewer() // Microsoft Logger //.Logging.AddDefaultDataStoreLogger(); // uncomment to use custom logging colors (note: System.Drawing namespace) // .Logging.AddDefaultDataStoreLogger(options => { options.Colors[LogLevel.Trace] = new() { Foreground = Color.White, Background = Color.DarkGray }; options.Colors[LogLevel.Debug] = new() { Foreground = Color.White, Background = Color.Gray }; options.Colors[LogLevel.Information] = new() { Foreground = Color.White, Background = Color.DodgerBlue }; options.Colors[LogLevel.Warning] = new() { Foreground = Color.White, Background = Color.Orchid }; }); IServiceCollection services = builder.Services; services .AddSingleton() .AddSingleton(service => new MainWindow { DataContext = service.GetRequiredService() }); _host = builder.Build(); _cancellationTokenSource = new(); try { LogStartingMode(); // set and show desktop.MainWindow = _host.Services.GetRequiredService(); desktop.ShutdownRequested += OnShutdownRequested; // startup background services _ = _host.StartAsync(_cancellationTokenSource.Token); } catch (OperationCanceledException) { // skip } catch (Exception ex) { ShowMessageBox("Unhandled Error", ex.Message); return; } } base.OnFrameworkInitializationCompleted(); } private static void DisableAvaloniaDataAnnotationValidation() { // Get an array of plugins to remove var dataValidationPluginsToRemove = BindingPlugins.DataValidators.OfType().ToArray(); // remove each entry found foreach (var plugin in dataValidationPluginsToRemove) { BindingPlugins.DataValidators.Remove(plugin); } } private void OnShutdownRequested(object? sender, ShutdownRequestedEventArgs e) => _ = _host!.StopAsync(_cancellationTokenSource!.Token); #region Fields private IHost? _host; private CancellationTokenSource? _cancellationTokenSource; #endregion private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e) => ShowMessageBox("Unhandled Error", ((Exception)e.ExceptionObject).Message); private static void ShowMessageBox(string title, string message) { var box = MessageBoxManager.GetMessageBoxStandard( "Exception", text: message, ButtonEnum.Ok, Icon.Stop ); _ = box.ShowAsync().GetAwaiter(); } private void LogStartingMode() { // Get the Launch mode bool isDevelopment = string.Equals(Environment.GetEnvironmentVariable("DOTNET_MODIFIABLE_ASSEMBLIES"), "debug", StringComparison.OrdinalIgnoreCase); // initialize a logger & EventId ILogger logger = _host!.Services.GetRequiredService>(); EventId eventId = new EventId(id: 0, name: Assembly.GetEntryAssembly()!.GetName().Name); // log a test pattern for each log level logger.TestPattern(eventId: eventId); // log that we have started... logger.Emit(eventId, LogLevel.Information, $"Running in {(isDevelopment ? "Debug" : "Release")} mode"); } }