using Avalonia;
using IBKRTrader.App.Avalonia.Shell;
using IBKRTrader.Core.Logging;
using IBKRTrader.Core.Modularity;
using IBKRTrader.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace IBKRTrader.App.Avalonia;
///
/// Einstiegspunkt der plattformneutralen Oberfläche.
///
/// Bewusst zweigeteilt: stellt den Host mit Persistenz,
/// Diensten und Modulen zusammen – ohne jeden Bezug zur Oberfläche. Erst danach wird Avalonia
/// daran gehängt. Derselbe Host trägt den kopflosen Linux-Dienst
/// (IBKRTrader.Daemon).
///
internal static class Program
{
[STAThread]
public static int Main(string[] args)
{
// Konstruktionsprüfung aller Fenster ohne Message-Loop und ohne laufende Dienste.
if (HasFlag(args, "--smoke-ui")) return SmokeUi.Run();
var modules = AppHostBuilder.CreateModules();
using var host = AppHostBuilder.Build(modules, ShellServices.Register);
AppHostBuilder.RunStartupChecks(host.Services);
var logger = host.Services.GetRequiredService();
logger.Info("Core", "=== IBKRTrader startet ===");
logger.Info("Core", $"Version: 1.0.0 | .NET {Environment.Version}");
host.Start();
StartModules(modules, logger);
try
{
App.Services = host.Services;
BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
return 0;
}
finally
{
// Geordnetes Herunterfahren – erst nachdem die Oberfläche beendet ist.
StopModules(modules, logger);
host.StopAsync(TimeSpan.FromSeconds(30)).GetAwaiter().GetResult();
}
}
/// Von Avalonia erwartete Fabrikmethode (auch vom XAML-Previewer genutzt).
public static AppBuilder BuildAvaloniaApp() =>
AppBuilder.Configure()
.UsePlatformDetect()
.WithInterFont()
.LogToTrace();
private static void StartModules(IReadOnlyList modules, LoggingService logger)
{
foreach (var module in modules)
{
try { module.StartAsync(default).GetAwaiter().GetResult(); }
catch (Exception ex) { logger.Error(module.Name, $"{module.Name}: Start fehlgeschlagen.", ex); }
}
logger.Info("Core", "IBKRTrader bereit.");
}
private static void StopModules(IReadOnlyList modules, LoggingService logger)
{
foreach (var module in modules)
{
try { module.StopAsync(default).GetAwaiter().GetResult(); }
catch (Exception ex) { logger.Warn(module.Name, $"{module.Name}: Stopp fehlgeschlagen: {ex.Message}"); }
}
}
private static bool HasFlag(string[] args, string flag) =>
args.Any(a => string.Equals(a, flag, StringComparison.OrdinalIgnoreCase));
}