refactor: rename App.axaml -> Application.axaml

This commit is contained in:
2026-04-20 15:18:14 +03:00
parent 437107ecb8
commit 469fc7b8aa
2 changed files with 0 additions and 0 deletions
+155
View File
@@ -0,0 +1,155 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using Avalonia.Threading;
using GSS2.ViewModels;
using GSS2.Views;
using GSS2.UI.Core;
using GSS2.UI.Core.Services;
using GSS2.UI.Core.ViewModels;
namespace GSS2;
public partial class Application : Avalonia.Application
{
private readonly IServiceProvider _services;
private readonly bool _fullscreen;
private readonly ILogger<Application> _logger;
private readonly DependencyInjectionViewLocator _viewLocator;
private bool _allShutdownSequencesRunning;
public NavigationService Navigation { get; }
public Application(IServiceProvider services, bool fullscreen = false)
{
_services = services;
_fullscreen = fullscreen;
// Создаём AvaloniaLogSink, который перенаправляет логи из Avalonia в хост
var loggerFactory = _services.GetRequiredService<ILoggerFactory>();
Avalonia.Logging.Logger.Sink = new AvaloniaLogSink(loggerFactory);
// Создаём DependencyInjectionViewLocator
_logger = _services.GetRequiredService<ILogger<Application>>();
_viewLocator = _services.GetRequiredService<DependencyInjectionViewLocator>();
Navigation = _services.GetRequiredService<NavigationService>();
}
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
// Добавляем наш DependencyInjectionViewLocator в DataTemplates приложения
DataTemplates.Add(_viewLocator);
}
public override void OnFrameworkInitializationCompleted()
{
// Получаем lifetime хоста
var hostLifetime = _services.GetRequiredService<IHostApplicationLifetime>();
// Регистрируем обработчик начатия Ctrl+C
Console.CancelKeyPress += (_, _) =>
{
_logger.LogInformation("Закрытие приложения вызвано из консоли");
hostLifetime.StopApplication();
};
// Создаём обработчик события закрытия хоста
hostLifetime.ApplicationStopped.Register(() =>
{
// Если всё что нужно для закрытия приложения уже вызвано, то ничего не делаем
if (_allShutdownSequencesRunning)
return;
// Иначе это событие вызвано не из интерфейса и графический интерфейс нужно закрыть
Dispatcher.UIThread.InvokeShutdown();
_allShutdownSequencesRunning = true;
});
// Создаём обработчик события закрытия графического интерфейса
Dispatcher.UIThread.ShutdownStarted += (_, _) =>
{
// Если всё что нужно для закрытия приложения уже вызвано, то ничего не делаем
if (_allShutdownSequencesRunning)
return;
// Иначе это событие вызвано из интерфейса и хост нужно закрыть
_logger.LogInformation("Закрытие приложения вызвано из интерфейса");
hostLifetime.StopApplication();
_allShutdownSequencesRunning = true;
};
// ApplicationLifetime == null, то невозможно определить в какой среде мы запускаемся,
// но такого быть не должно
if (ApplicationLifetime is null)
{
_logger.LogCritical("Приложение не может быть полностью инициализировано, ApplicationLifetime == null");
// Я не уверен, будет ли правильно в данном классе вместо выбрасывания исключений,
// использовать Environment.Exit,
// но если использовать исключения, то их может поймать какой-нибудь обработчик,
// а Environment.Exit гарантированно завершит текущий процесс
hostLifetime.StopApplication();
Environment.Exit(1);
}
// Создаём начальный элемент управления и переходим к нему
var mainView = new MainView()
{
DataContext = _services.GetRequiredService<MainViewModel>()
};
// var mainView = new GSS2.UI.Core.Views.CameraView(_services.GetService<ILogger<GSS2.UI.Core.Views.CameraView>>()!)
// {
// DataContext = _services.GetRequiredService<GSS2.UI.Core.ViewModels.CameraViewModel>()
// };
// Создаём главный элемент управления
// на основании типа ApplicationLifetime, который зависит от того как мы запустили приложение
// StartWithClassicDesktopLifetime IClassicDesktopStyleApplicationLifetime
// StartLinuxDrm ISingleViewApplicationLifetime
switch (ApplicationLifetime)
{
case IClassicDesktopStyleApplicationLifetime desktop:
_logger.LogInformation("Приложение запускается в классическом режиме");
_logger.LogInformation("Приложение запускается в {} режиме", _fullscreen ? "полноэкранном" : "оконном");
// Создаём главное окно
var mainWindow = new MainWindow()
{
DataContext = new MainWindowViewModel()
{
WindowDecorations = _fullscreen ? Avalonia.Controls.WindowDecorations.None : Avalonia.Controls.WindowDecorations.Full,
Topmost = _fullscreen,
WindowState = _fullscreen ? Avalonia.Controls.WindowState.FullScreen : Avalonia.Controls.WindowState.Normal
},
};
desktop.MainWindow = mainWindow;
// Переключаемся на начальный элемент управления
Navigation.NavigateTo(mainView);
break;
case ISingleViewApplicationLifetime singleView:
_logger.LogInformation("Приложение запускается в режиме отображение единой формы");
// Просто устанавливаем главным элементом управления начальный элемент
singleView.MainView = mainView;
break;
default:
_logger.LogCritical("Приложение не может быть полностью инициализировано, ApplicationLifetime имеет неизвестный тип, наследованный от: {}", string.Join(", ", ApplicationLifetime.GetType().GetInterfaces().Select(i => i.FullName)));
hostLifetime.StopApplication();
Environment.Exit(1);
break;
}
base.OnFrameworkInitializationCompleted();
}
}