TelegramBots / Telegram.Bot.Examples

Examples for the Telegram.Bot C# Library
MIT License
630 stars 289 forks source link

Struggling with services lifetimes #498

Closed dmrzn closed 2 months ago

dmrzn commented 11 months ago

Hi Guys!

I'm using Telegram.Bot.Examples.Polling as a mechanism for my bot. I'm trying to have a service class that is a dependency of UpdateHandler class the following way: The service should be constructed per each update handling (UpdateHandler call)

My initial attempt was to register that service as a scoped service but I found out that my scoped services live across multiple updates.

I'm looking at PollingServiceBase class and see that a scope is being created there:

    // Create new IServiceScope on each iteration.
    // This way we can leverage benefits of Scoped TReceiverService
    // and typed HttpClient - we'll grab "fresh" instance each time
    using var scope = _serviceProvider.CreateScope();
    var receiver = scope.ServiceProvider.GetRequiredService<TReceiverService>();

    await receiver.ReceiveAsync(stoppingToken);

My question is: What does the scope span in PollingServiceBase.DoWork method?

The call of receiver.ReceiveAsync(stoppingToken) never completes: Internally it calls ITelegramBotClient.ReceiveAsync extension method which in its turn calls DefaultUpdateReceiver.ReceiveAsync which internally is implemented using while (!cancellationToken.IsCancellationRequested) loop.

Fedorus commented 11 months ago

If you need scoped solution you can try: https://github.com/TgBotFramework/TgBotFramework.Template

dmrzn commented 11 months ago

Still would be great to know the motivation of the scope creating code I mentioned above.

wiz0u commented 2 months ago

as I understand it, _serviceProvider.CreateScope(); doesn't create a new scope really, it's just a way to obtain a resolver service to find our globally scoped ReceiverService already created in Program.cs: services.AddScoped<ReceiverService>();