using System; using System.ComponentModel; using System.Windows; using Microsoft.Extensions.DependencyInjection; using Pf2e.Database; using Pf2e.Scrapper; using Pf2e.Scrapper.Helpers; using Pf2e.Scrapper.Processors; using Pf2e.Scrapper.Processors.Collection; using Pf2e.WPF.EntityViewer; using Pf2e.WPF.Progress; using Pf2e.WPF.Start; using Slugify; namespace Pf2e.WPF; public sealed class ImportApplication : Application { public ImportApplication( IServiceProvider serviceProvider, ApplicationSettings settings, ProcessorCollection processors ) { ServiceProvider = serviceProvider; Settings = settings; Processors = processors; CurrentStage = ApplicationStage.InitialSettings; //CurrentStage = ApplicationStage.Viewer; } #region "Поля" /// /// Текущий этап выполнения программы. /// public ApplicationStage CurrentStage { get => _currentStage; set { ApplicationStage oldValue = _currentStage; _currentStage = value; CloseStage(oldValue); StartStage(_currentStage); } } private ApplicationStage _currentStage = ApplicationStage.BootUp; #endregion #region "Жизненный цикл" private StartForm? _startFormWpf; private ProgressForm? _progressFormWpf; private EntityForm? _entityForm; private Window? CurrentWpfForm { get; set; } public delegate void ApplicationStateChangeDelegate(object sender, ApplicationStage nextStage); private void StartStage(ApplicationStage stage) { switch (stage) { case ApplicationStage.BootUp: throw new( $"{CurrentStage} никогда не должен быть установлен через поле \"CurrentStage\"." ); case ApplicationStage.InitialSettings: _startFormWpf = ActivatorUtilities.CreateInstance(ServiceProvider); _startFormWpf.WindowStartupLocation = WindowStartupLocation.CenterScreen; _startFormWpf.Closing += Wpf_HandleFormClosing; _startFormWpf.ApplicationStateChange += ApplicationStateChange; _startFormWpf.Show(); CurrentWpfForm = _startFormWpf; break; case ApplicationStage.ImportProcess: ProcessorExecutor executor = ActivatorUtilities.CreateInstance( ServiceProvider ); _progressFormWpf = ActivatorUtilities.CreateInstance(ServiceProvider); _progressFormWpf.WindowStartupLocation = WindowStartupLocation.CenterScreen; _progressFormWpf.Closing += Wpf_HandleFormClosing; _progressFormWpf.ApplicationStateChange += ApplicationStateChange; _progressFormWpf.Show(); CurrentWpfForm = _progressFormWpf; executor.Start(); break; case ApplicationStage.Viewer: _entityForm = ActivatorUtilities.CreateInstance(ServiceProvider); _entityForm.WindowStartupLocation = WindowStartupLocation.CenterScreen; _entityForm.Closing += Wpf_HandleFormClosing; _entityForm.ApplicationStateChange += ApplicationStateChange; _entityForm.Show(); CurrentWpfForm = _entityForm; break; default: throw new ArgumentOutOfRangeException(); } } private void CloseStage(ApplicationStage stage) { CurrentWpfForm = null; switch (stage) { case ApplicationStage.BootUp: // Нечего закрывать break; case ApplicationStage.InitialSettings: _startFormWpf!.Hide(); _startFormWpf!.Close(); _startFormWpf = null; break; case ApplicationStage.ImportProcess: _progressFormWpf!.Hide(); _progressFormWpf!.Close(); _progressFormWpf = null; break; case ApplicationStage.Viewer: _entityForm!.Hide(); _entityForm!.Close(); _entityForm = null; break; default: throw new ArgumentOutOfRangeException(nameof(stage)); } } #endregion #region "События" public void ApplicationStateChange(object sender, ApplicationStage nextStage) { if (sender?.Equals(CurrentWpfForm) ?? false) { CurrentStage = nextStage; } } private void Wpf_HandleFormClosing(object? sender, CancelEventArgs e) { if (sender?.Equals(CurrentWpfForm) ?? false) { Shutdown(); } else { e.Cancel = true; } } #endregion #region "Внедрение зависимостей" public IServiceProvider ServiceProvider { get; } public ApplicationSettings Settings { get; } public ProcessorCollection Processors { get; } public static void RegisterServices(IServiceCollection services) { // Контекст базы данных services.AddEntityFrameworkNpgsql(); services.AddDbContext(); //services.AddDbContextPool(options => //{ // options.Us //}); // Основная программа services.AddSingleton(); // Настройки программы services.AddSingleton(); // Набор процессоров services.AddSingleton(); // Помощник идентификации базы данных services.AddSingleton(); // Помощник создание URL-совместимых названий services.AddTransient(); // Счётчик прогресса services.AddSingleton(); } #endregion } public enum ApplicationStage { BootUp, InitialSettings, ImportProcess, Viewer, Rules, }