Files
IBKRTrader/UI/ModuleViews.cs
T
RichardandClaude Opus 5 123f38ab6f L1a: Core und Module von WinForms entkoppeln - net10.0 statt net10.0-windows
Core, alle drei Module und das Testprojekt tragen keinen UI-Code mehr und
bauen fuer linux-x64. Nur noch IBKRTrader.App ist Windows-gebunden.

UI-Contract toolkit-neutral (Vorbild: PolytraderSharp):
- ModuleView.CreateForm (Func<Form>) -> CreateView (Func<object>)
- ModuleView.Icon (System.Drawing.Image) -> IconKey (string).
  System.Drawing.Common ist seit .NET 7 Windows-only und wirft auf Linux.
- WindowMenu.cs war reine WinForms-Umsetzung -> in die Shell verschoben.

LoggingService haelt keine RichTextBox mehr, sondern meldet Eintraege ueber
event EntryWritten. Einfaerbung und UI-Thread-Wechsel liegen jetzt im
LogPanelController der Shell. Nebenbei: ToUpper() -> ToUpperInvariant()
(tr-TR haette aus "info" ein "İNFO" gemacht) und \r\n -> Environment.NewLine.

Die drei Modul-Fenster liegen jetzt unter UI/Views/Modules/; RegisterUi der
Module ist bewusst leer, die Shell registriert sie zentral ueber
UI/ModuleViews.cs (nur fuer tatsaechlich geladene Module). ViewIcons loest
IconKey gegen die PNG-Ressourcen auf - dieselben Schluessel bekommt spaeter
die Avalonia-Shell.

UiConstructionTests entfernt: die Konstruktionspruefung deckt --smoke-ui ab,
das Testprojekt braucht dafuer keine UI-Referenz mehr. Der Test
RegisterUi_RegistersMainView haelt jetzt das Gegenteil fest - das Modul darf
nichts registrieren, sonst waere es wieder toolkit-gebunden.

Verifiziert: Build 0 Fehler/0 Warnungen, 163 Tests gruen, --smoke-ui
konstruiert alle 7 Fenster, und Core + 3 Module + Tests bauen fuer linux-x64.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 22:38:01 +02:00

72 lines
3.2 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.Analytics;
using IBKRTrader.Core.Logging;
using IBKRTrader.Core.Modularity;
using IBKRTrader.Core.Trading;
using IBKRTrader.Core.Workers;
using IBKRTrader.Modules.Accounting.Persistence;
using IBKRTrader.Modules.Accounting.Services;
using IBKRTrader.Modules.CongressTrading.Database;
using IBKRTrader.Modules.Supervisor.Agent;
using IBKRTrader.Modules.Supervisor.Persistence;
using IBKRTrader.Modules.Supervisor.Services;
using IBKRTrader.UI.Views.Modules;
using Microsoft.Extensions.DependencyInjection;
namespace IBKRTrader.UI;
/// <summary>
/// Registriert die Fenster der Module bei der Shell.
///
/// <para><b>Warum hier und nicht im Modul?</b> Ein Modul, das sein eigenes Fenster erzeugt, muss das
/// UI-Toolkit referenzieren und wäre damit an WinForms bzw. Avalonia gebunden. Genau das verhindert
/// den kopflosen Linux-Betrieb. Die Modulprojekte bleiben deshalb frei von UI-Code; ihr
/// <c>RegisterUi</c> ist leer, und die Shell verdrahtet die Fenster zentral. Die Modul-Dienste
/// kommen unverändert aus dem DI-Container.</para>
///
/// <para>Registriert wird nur, was auch geladen ist: fehlt ein Modul in dieser Sitzung, entfällt
/// sein Fenster, und der Launcher zeigt es gar nicht erst an.</para>
/// </summary>
public static class ModuleViews
{
public static void Register(IModuleUiHost host, IServiceProvider sp)
{
RegisterIfLoaded(sp, "CongressTrading", () => host.RegisterView(new ModuleView
{
Id = "congresstrading.main", Title = "Congress Trading", Group = "CongressTrading", Order = 100,
CreateView = () => new CongressTradingForm(
sp.GetRequiredService<CongressRepository>(),
sp.GetRequiredService<WorkerEngine>(),
sp.GetRequiredService<IPortfolioService>(),
sp.GetRequiredService<LoggingService>())
}));
RegisterIfLoaded(sp, "Supervisor", () => host.RegisterView(new ModuleView
{
Id = "supervisor.main", Title = "Supervisor", Group = "Supervisor", Order = 300,
CreateView = () => new SupervisorMainForm(
sp.GetRequiredService<SupervisorAgent>(),
sp.GetRequiredService<DossierService>(),
sp.GetRequiredService<ISupervisorReportRepository>(),
sp.GetRequiredService<LoggingService>())
}));
RegisterIfLoaded(sp, "Accounting", () => host.RegisterView(new ModuleView
{
Id = "accounting.main", Title = "Accounting", Group = "Accounting", Order = 400,
CreateView = () => new AccountingMainForm(
sp.GetRequiredService<ILedgerRepository>(),
sp.GetRequiredService<IIngestRunRepository>(),
sp.GetRequiredService<AccountingReportService>(),
sp.GetRequiredService<AccountingIngestService>(),
sp.GetRequiredService<LoggingService>())
}));
}
/// <summary>Registriert die Ansicht nur, wenn das Modul in dieser Sitzung geladen ist.</summary>
private static void RegisterIfLoaded(IServiceProvider sp, string moduleName, Action register)
{
if (sp.GetServices<IModule>().Any(m => string.Equals(m.Name, moduleName, StringComparison.OrdinalIgnoreCase)))
register();
}
}