- Fenster-Menue: WindowMenu fuellt die oberste MenuStrip mit Top-Level-Eintraegen nebeneinander (mit Icon) statt Untermenue "Fenster"; ModuleView.Icon zentral in der App zugewiesen (AssignMenuIcons). Kein miFenster mehr im Launcher-Designer. - Sicheres Beenden: ShutdownConfirmDialog (10s-Timer sperrt "Jetzt beenden", Abbrechen jederzeit) via IModuleUiHost.RequestShutdown(). Nur der Launcher (Hauptprozess) bietet "Beenden"; andere Fenster nur "Fenster schliessen" (kein App-Shutdown, Module laufen weiter). Launcher-Schliessen-X routet ueber dieselbe Abfrage. - Modul-Aktivierung (restart-basiert): ServerSettings.DisabledModules, in Program.Main vor der DI-Registrierung gefiltert -> deaktivierte Module werden nicht geladen. Dashboard-Tab "Module" zeigt Status + schaltet um (Hinweis: greift nach Neustart). Optionaler IPolyTraderModule.GetActivationBlocker fuer "nicht aktivierbar"-Info. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
52 lines
2.3 KiB
C#
52 lines
2.3 KiB
C#
using System;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
namespace PolyTrader.Core.Modularity
|
|
{
|
|
/// <summary>
|
|
/// Vertrag für ein PolyTrader-Modul. Module referenzieren nur den Core, niemals
|
|
/// einander. Ein Modul kapselt einen eigenständigen Funktionsbereich (z.B. Copytrading)
|
|
/// mit eigenen Services, Jobs, DB-Objekten sowie eigenen UI-Ansichten und Settings-Sektionen.
|
|
/// </summary>
|
|
public interface IPolyTraderModule
|
|
{
|
|
/// <summary>Eindeutiger Anzeigename des Moduls, z.B. "CopyTrading".</summary>
|
|
string Name { get; }
|
|
|
|
/// <summary>
|
|
/// Namespace-Präfix für die DB-Objekte des Moduls (z.B. "ct_"), damit sich Module
|
|
/// nicht in die Quere kommen.
|
|
/// </summary>
|
|
string DbPrefix { get; }
|
|
|
|
/// <summary>
|
|
/// Registriert die Services/Jobs des Moduls im DI-Container. Wird beim App-Start
|
|
/// aufgerufen, bevor der Host gebaut wird.
|
|
/// </summary>
|
|
void RegisterServices(IServiceCollection services, IConfiguration configuration);
|
|
|
|
/// <summary>
|
|
/// Registriert die UI-Ansichten des Moduls bei der Shell (Launcher). Die Shell öffnet
|
|
/// jede Ansicht auf Wunsch in einem eigenen Host-Fenster. Module liefern eigene Forms;
|
|
/// die Shell bleibt modul-agnostisch. Über <paramref name="services"/> lösen Module ihre
|
|
/// Abhängigkeiten (Repos, State) für die View-Erzeugung auf.
|
|
/// </summary>
|
|
void RegisterUi(IModuleUiHost host, IServiceProvider services);
|
|
|
|
/// <summary>
|
|
/// Optionale Vorab-Prüfung, ob das Modul aktiviert werden kann. Gibt <c>null</c> zurück, wenn
|
|
/// aktivierbar, sonst einen kurzen, im Dashboard anzeigbaren Grund (z.B. „Alchemy-API-Key fehlt").
|
|
/// Default: immer aktivierbar. Module überschreiben dies bei harten Voraussetzungen.
|
|
/// </summary>
|
|
string? GetActivationBlocker(IConfiguration configuration) => null;
|
|
|
|
/// <summary>Wird nach der Core-Hydration gestartet (kein Anlaufen gegen leeren State).</summary>
|
|
Task StartAsync(CancellationToken cancellationToken);
|
|
|
|
Task StopAsync(CancellationToken cancellationToken);
|
|
}
|
|
}
|