.Net 5. Cannot access a disposed object. Object name: 'IServiceProvider'
Задеплоил приложение на heroku, после деплоя все работает. Если приложение не используется N время, то падает пул и сервер засыпает. При рестарте пула не работают сервисы, которые зарегистрированы через AddSingleton().
Я решил поменять регистрацию на AddTransied(), но теперь возникает ошибка при инициализации IServiceProvider(Cannot access a disposed object) в хендлере Mideatora, т.е. вызов хендлера не происходит и возникает исключение. Что я делаю не так?
Регистрирую так:
services.AddTransient<IBotService, BotService>()
services.AddTransient<IMessageHandlerService, MessageHandlerService>()
services.AddMediatR(typeof(GetClientByTelegramChatIdHandler).GetTypeInfo().Assembly)
Вызываю сервисы через сервис BotService, на который тоже перерегистрировал через AddTransied. Через сервис обрабатываются события:
public class BotService : IBotService {
public async Task Watch() {
if (_botClient.IsReceiving) {
return;
}
await _botClient.SetWebhookAsync("");
_botClient.OnMessage += BotOnMessage;
_botClient.OnCallbackQuery += BotOnCallback;
_botClient.StartReceiving();
}
private async void BotOnMessage(object sender, MessageEventArgs eventMessage) {
try {
await _messageHandlerService.HandleText(eventMessage.Message);
}
catch(Exception e) {
_logger.LogError($"Error on client {eventMessage.Message.Chat.Id}. {e.Message}");
}
}
}
Вызов медиатора:
public class MessageHandlerService : IMessageHandlerService {
public async Task HandleText(Telegram.Bot.Types.Message message) {
if (message == null || string.IsNullOrWhiteSpace(message.Text)) {
return;
}
var client = await _mediator.Send(new GetClientByTelegramChatId(message.Chat.Id));
}
Хендлер:
public class GetClientByTelegramChatIdHandler : IRequestHandler<GetClientByTelegramChatId, TelegramClientDto> {
private readonly IServiceProvider _serviceProvider;
private readonly IMapper _mapper;
public GetClientByTelegramChatIdHandler(IServiceProvider serviceProvider, IMapper mapper) {
Contract.Requires(mapper != null);
_serviceProvider = serviceProvider;
_mapper = mapper;
}
public async Task<TelegramClientDto> Handle(GetClientByTelegramChatId request, CancellationToken cancellationToken) {
using var scope = _serviceProvider.CreateScope();
var repository = scope.ServiceProvider.GetRequiredService<IDbRepository<TelegramClient>>();
var clients = await repository.GetAsync();
var client = clients.ToList().FirstOrDefault(c => c.ChatId == request.ChatId);
return _mapper.Map<TelegramClientDto>(client);
}