fix services

This commit is contained in:
Leonid Pershin
2025-10-17 02:59:56 +03:00
parent d64c4742cf
commit 392e6bc7f5
3 changed files with 44 additions and 80 deletions

View File

@@ -146,20 +146,12 @@ try
builder.Services.AddScoped<ITelegramCommandProcessor, TelegramCommandProcessor>();
builder.Services.AddScoped<ITelegramMessageHandler, TelegramMessageHandler>();
// Регистрируем TelegramBotService как scoped и используем один экземпляр для интерфейса и HostedService
builder.Services.AddScoped<TelegramBotService>();
builder.Services.AddScoped<ITelegramBotService>(sp =>
sp.GetRequiredService<TelegramBotService>()
// Регистрируем TelegramBotService как singleton и hosted service
builder.Services.AddSingleton<ITelegramBotService, TelegramBotService>();
builder.Services.AddSingleton<IHostedService>(provider =>
(IHostedService)provider.GetRequiredService<ITelegramBotService>()
);
// Создаем обертку для HostedService, которая создает scope
builder.Services.AddSingleton<IHostedService>(sp =>
{
var serviceProvider = sp.GetRequiredService<IServiceProvider>();
var logger = sp.GetRequiredService<ILogger<TelegramBotHostedService>>();
return new TelegramBotHostedService(serviceProvider, logger);
});
// Регистрируем Health Checks
builder
.Services.AddHealthChecks()

View File

@@ -1,6 +1,6 @@
using ChatBot.Models.Configuration;
using ChatBot.Services.Telegram.Interfaces;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Telegram.Bot;
using Telegram.Bot.Polling;
using Telegram.Bot.Types;
@@ -11,41 +11,41 @@ namespace ChatBot.Services.Telegram.Services
/// <summary>
/// Основной сервис Telegram бота
/// </summary>
public class TelegramBotService : BackgroundService, ITelegramBotService
public class TelegramBotService : ITelegramBotService, IHostedService
{
private readonly ILogger<TelegramBotService> _logger;
private readonly ITelegramBotClient _botClient;
private readonly ITelegramMessageHandler _messageHandler;
private readonly ITelegramErrorHandler _errorHandler;
private readonly IServiceProvider _serviceProvider;
private CancellationTokenSource? _cancellationTokenSource;
public TelegramBotService(
ILogger<TelegramBotService> logger,
ITelegramBotClient botClient,
ITelegramMessageHandler messageHandler,
ITelegramErrorHandler errorHandler
IServiceProvider serviceProvider
)
{
_logger = logger;
_botClient = botClient;
_messageHandler = messageHandler;
_errorHandler = errorHandler;
_serviceProvider = serviceProvider;
}
/// <summary>
/// Запускает бота
/// </summary>
public override async Task StartAsync(CancellationToken cancellationToken)
public async Task StartAsync(CancellationToken cancellationToken = default)
{
var receiverOptions = new ReceiverOptions
{
AllowedUpdates = new[] { UpdateType.Message },
};
_cancellationTokenSource = new CancellationTokenSource();
_botClient.StartReceiving(
updateHandler: _messageHandler.HandleUpdateAsync,
errorHandler: _errorHandler.HandlePollingErrorAsync,
updateHandler: HandleUpdateAsync,
errorHandler: HandlePollingErrorAsync,
receiverOptions: receiverOptions,
cancellationToken: cancellationToken
cancellationToken: _cancellationTokenSource.Token
);
var botInfo = await GetBotInfoAsync(cancellationToken);
@@ -62,10 +62,12 @@ namespace ChatBot.Services.Telegram.Services
/// <summary>
/// Останавливает бота
/// </summary>
public override async Task StopAsync(CancellationToken cancellationToken)
public Task StopAsync(CancellationToken cancellationToken = default)
{
_logger.LogInformation("Stopping Telegram bot service...");
await base.StopAsync(cancellationToken);
_cancellationTokenSource?.Cancel();
_cancellationTokenSource?.Dispose();
return Task.CompletedTask;
}
/// <summary>
@@ -84,15 +86,31 @@ namespace ChatBot.Services.Telegram.Services
}
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
private async Task HandleUpdateAsync(
ITelegramBotClient botClient,
Update update,
CancellationToken cancellationToken
)
{
await StartAsync(stoppingToken);
// Create a new scope for each message processing
using var scope = _serviceProvider.CreateScope();
var messageHandler =
scope.ServiceProvider.GetRequiredService<ITelegramMessageHandler>();
// Keep the service running
while (!stoppingToken.IsCancellationRequested)
{
await Task.Delay(1000, stoppingToken);
}
await messageHandler.HandleUpdateAsync(botClient, update, cancellationToken);
}
private async Task HandlePollingErrorAsync(
ITelegramBotClient botClient,
Exception exception,
CancellationToken cancellationToken
)
{
// Create a new scope for error handling
using var scope = _serviceProvider.CreateScope();
var errorHandler = scope.ServiceProvider.GetRequiredService<ITelegramErrorHandler>();
await errorHandler.HandlePollingErrorAsync(botClient, exception, cancellationToken);
}
}
}

View File

@@ -1,46 +0,0 @@
using ChatBot.Services.Telegram.Interfaces;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace ChatBot.Services
{
/// <summary>
/// Hosted service wrapper for TelegramBotService to handle scoped dependencies
/// </summary>
public class TelegramBotHostedService : IHostedService
{
private readonly IServiceProvider _serviceProvider;
private readonly ILogger<TelegramBotHostedService> _logger;
private ITelegramBotService? _botService;
public TelegramBotHostedService(
IServiceProvider serviceProvider,
ILogger<TelegramBotHostedService> logger
)
{
_serviceProvider = serviceProvider;
_logger = logger;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Starting Telegram Bot Hosted Service...");
using var scope = _serviceProvider.CreateScope();
_botService = scope.ServiceProvider.GetRequiredService<ITelegramBotService>();
await _botService.StartAsync(cancellationToken);
}
public async Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Stopping Telegram Bot Hosted Service...");
if (_botService != null)
{
await _botService.StopAsync(cancellationToken);
}
}
}
}