Files
IBKRTrader/Form1.cs
T
Richard af398353f0 @
Phase 1: Modul-System formalisiert (IModule + ModuleRegistry)

- Core/Modules/IModule.cs: Vertrag (Key, DisplayName, Description, Version,
  RegisterServices, InitializeAsync, GetWorkers, CreateWindow)
- Core/Modules/ModuleRegistry.cs
- CongressTradingModule auf IModule umgestellt (instanzbasiert, Platzhalter-Fenster)
- Program.cs iteriert ueber IModule[] + Registry; Form1 initialisiert Module ueber Registry
- Testbarkeit: WorkerBase DB-Log-Seam (virtuell); CapitolTradesScraper.ParseTradesFromHtml
  extrahiert (offline gegen ct_raw.html testbar)
- Tests: ModuleRegistry, CongressTradingModule, WorkerBase, CapitolTradesScraper -> 15/15 gruen

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-27 10:07:47 +02:00

137 lines
4.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using IBKRTrader.Core.Database.Migrations;
using IBKRTrader.Core.Logging;
using IBKRTrader.Core.Modules;
using IBKRTrader.Core.Settings;
using IBKRTrader.Core.Workers;
using IBKRTrader.UI;
using Microsoft.Extensions.DependencyInjection;
namespace IBKRTrader;
public partial class Form1 : Form
{
private readonly LoggingService _logger;
private readonly WorkerEngine _workerEngine;
private readonly SettingsService _settings;
private readonly CoreMigrations _migrations;
private readonly IBKRMigrations _ibkrMigrations;
private readonly IServiceProvider _services;
private LogPanelController? _logPanel;
public Form1(
LoggingService logger,
WorkerEngine workerEngine,
SettingsService settings,
CoreMigrations migrations,
IBKRMigrations ibkrMigrations,
IServiceProvider services)
{
InitializeComponent();
_logger = logger;
_workerEngine = workerEngine;
_settings = settings;
_migrations = migrations;
_ibkrMigrations = ibkrMigrations;
_services = services;
}
// ─── Form-Events ──────────────────────────────────────────────────────────
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
InitializeLogPanel();
InitializeWorkerList();
InitializeSettingsGrid();
_ = StartupAsync();
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
// Worker sauber beenden (feuert & vergisst Form muss kurz warten)
_workerEngine.StopAllAsync().GetAwaiter().GetResult();
}
// ─── Initialisierung ──────────────────────────────────────────────────────
private void InitializeLogPanel()
{
// RichTextBox auf Dock.Fill setzen
rtb_logs.Dock = DockStyle.Fill;
_logPanel = new LogPanelController(rtb_logs, _logger);
// LogLevel aus Settings setzen
var levelStr = _settings.Settings.Logging.Level;
if (Enum.TryParse<AppLogLevel>(levelStr, true, out var level))
_logger.SetMinLevel(level);
}
private void InitializeWorkerList()
{
WorkerListBindingSource.Setup(dgv_workerlist, _workerEngine.WorkerInfos);
}
private void InitializeSettingsGrid()
{
pg_settings.SelectedObject = _settings.Settings;
}
// ─── Async Startup ────────────────────────────────────────────────────────
private async Task StartupAsync()
{
_logger.Info("Core", "=== IBKRTrader startet ===");
_logger.Info("Core", $"Version: 1.0.0 | .NET {Environment.Version}");
// DB-Verbindung testen und Core-Migrationen laufen lassen
try
{
_logger.Info("Core", "Verbinde mit Datenbank...");
await _migrations.RunAsync();
await _ibkrMigrations.RunAsync();
}
catch (Exception ex)
{
_logger.Error("Core", "Core-Datenbankfehler beim Start.", ex);
}
// Modul-Migrationen: über die Registry iterieren (Core kennt kein Modul).
var registry = _services.GetRequiredService<ModuleRegistry>();
foreach (var module in registry.Modules)
{
try
{
await module.InitializeAsync(_services);
}
catch (Exception ex)
{
_logger.Error(module.Key, $"{module.DisplayName}: Initialisierung fehlgeschlagen.", ex);
}
}
// Worker starten
await _workerEngine.StartAllAsync();
_logger.Info("Core", "IBKRTrader bereit.");
UpdateStatusBar("Bereit");
}
// ─── StatusBar ────────────────────────────────────────────────────────────
private void UpdateStatusBar(string text)
{
if (statusStrip1.InvokeRequired)
statusStrip1.BeginInvoke(() => UpdateStatusBar(text));
else
{
// Vorhandenes Label nutzen oder neues anlegen
if (statusStrip1.Items.Count == 0)
statusStrip1.Items.Add(new ToolStripStatusLabel());
statusStrip1.Items[0].Text = $"Status: {text} | {DateTime.Now:HH:mm:ss}";
}
}
}