using DailyDigestWorker; using DailyDigestWorker.Configuration; // Добавляем using для наших классов конфигурации using DailyDigestWorker.Services; using Microsoft.Extensions.Options; // Для IOptions using Telegram.Bot; // Для Telegram.Bot using WTelegram; // Для WTelegramClient using System.Text; Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); // --- Используем современный стиль Program.cs без явного класса --- var builder = Host.CreateApplicationBuilder(args); // Используем новый стиль ApplicationBuilder // --- Конфигурация --- // Конфигурация уже настроена builder.Configuration (читает appsettings.json, env vars, user secrets и т.д.) // Привязываем секции конфигурации к нашим классам POCO // Это позволит внедрять их через IOptions builder.Services.Configure(builder.Configuration.GetSection("BotConfiguration")); builder.Services.Configure(builder.Configuration.GetSection("TelegramClient")); builder.Services.Configure(builder.Configuration.GetSection("ApiKeys")); builder.Services.Configure(builder.Configuration.GetSection("DataSourceUrls")); builder.Services.Configure(builder.Configuration.GetSection("GeminiSettings")); // Особая обработка для времени в SchedulingSettings builder.Services.Configure(builder.Configuration.GetSection("Scheduling")); // --- Регистрация сервисов (Dependency Injection) --- // 1. Регистрируем HttpClientFactory (для запросов к API погоды, валют, крипты, Gemini) builder.Services.AddHttpClient(); // 2. Регистрируем Telegram Bot Client (для ОТПРАВКИ сообщений) // Мы регистрируем его как Singleton, так как клиент потокобезопасен и должен быть один builder.Services.AddSingleton(sp => // sp - Service Provider { // Получаем конфигурацию бота через IOptions var botConfig = sp.GetRequiredService>().Value; if (string.IsNullOrWhiteSpace(botConfig.BotToken)) { // Выбрасываем исключение при запуске, если токен не задан - приложение не сможет работать throw new InvalidOperationException("Bot Token не сконфигурирован в appsettings.json или эквиваленте."); } return new TelegramBotClient(botConfig.BotToken); }); // 3. Регистрируем WTelegramClient (для ЧТЕНИЯ канала) // Тоже Singleton. WTelegramClient управляет своим состоянием подключения. builder.Services.AddSingleton(sp => // Регистрируем конкретный тип Client { var clientSettings = sp.GetRequiredService>().Value; var logger = sp.GetRequiredService>(); // Получаем логгер // Функция для получения конфигурационных данных для WTelegramClient string? GetConfig(string configKey) { switch (configKey) { case "api_id": return clientSettings.ApiId.ToString(); case "api_hash": return clientSettings.ApiHash; case "phone_number": return clientSettings.PhoneNumber; case "session_pathname": return clientSettings.SessionPath; // <--- ДОБАВИТЬ ЭТОТ CASE // При необходимости можно добавить обработку "password", "verification_code" и др. default: logger.LogWarning("WTelegramClient запросил неизвестный ключ конфигурации: {ConfigKey}", configKey); return null; // Возвращаем null для неизвестных ключей } } // WTelegramClient требует функцию для получения конфигурации var client = new WTelegram.Client(GetConfig); // Настраиваем уровень логирования для WTelegramClient (опционально, но полезно для отладки) // WTelegram сама использует Microsoft.Extensions.Logging, если он доступен // Можно установить глобальный уровень или здесь, например: // WTelegram.Helpers.Log = (level, message) => logger.Log((LogLevel)level, message); // Некорректную строку ниже мы УДАЛИЛИ return client; }); // 4. Регистрируем наши сервисы для получения данных builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); // 5. Регистрируем сервисы для обработки и отправки builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient();// <-- ДОБАВИТЬ ЭТУ СТРОКУ // 6. Регистрируем наш основной Worker Service (эта строка уже должна быть) builder.Services.AddHostedService(); // --- Сборка и запуск хоста --- var host = builder.Build(); host.Run();