using LazyBear.MCP.Services.ToolRegistry; using LazyBear.MCP.TUI.Components; using Microsoft.Extensions.Hosting; using RazorConsole.Core; namespace LazyBear.MCP.TUI; /// /// Запускает RazorConsole TUI как IHostedService в отдельном потоке, /// чтобы не блокировать ASP.NET Core pipeline. /// public sealed class TuiHostedService(IServiceProvider services, ILogger logger) : IHostedService { private Thread? _tuiThread; private CancellationTokenSource? _cts; public Task StartAsync(CancellationToken cancellationToken) { _cts = new CancellationTokenSource(); // Регистрируем все IToolModule-модули в ToolRegistryService var registry = services.GetRequiredService(); foreach (var module in services.GetServices()) { registry.RegisterModule(module); } _tuiThread = new Thread(RunTui) { IsBackground = true, Name = "RazorConsole-TUI" }; _tuiThread.Start(); logger.LogInformation("TUI запущен в фоновом потоке"); return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) { _cts?.Cancel(); logger.LogInformation("TUI остановлен"); return Task.CompletedTask; } private void RunTui() { try { var host = Host.CreateDefaultBuilder() .UseRazorConsole(configure: configure => { configure.ConfigureServices((_, svc) => { // Пробрасываем ключевые Singleton из основного DI-контейнера в TUI-контейнер svc.AddSingleton(services.GetRequiredService()); svc.AddSingleton(services.GetRequiredService()); }); }) .Build(); host.Run(); } catch (Exception ex) { logger.LogError(ex, "Ошибка в потоке TUI"); } } }