Я поддерживаю пакет интеграции, который позволяет моим пользователям интегрировать мою библиотеку с ASP.NET Core. Этот пакет должен быть совместим со всеми версиями ASP.NET Core, начиная с 2.1. При завершении работы приложения мой пакет интеграции должен иметь возможность выполнять асинхронную очистку и, к сожалению, не может зависеть от IAsyncDisposable
до Microsoft.Bcl.AsyncInterfaces
(см. ниже).
Таким образом, единственный способ, которым это представляется возможным, — это зарегистрировать реализацию IHostedService
. Его метод StopAsync
вызывается при завершении работы:
public sealed class ShutdownHostedService : IHostedService
{
public MyLibaryCleanupObject Obj;
public Task StartAsync(CancellationToken token) => Task.CompletedTask;
public Task StopAsync(CancellationToken token) => this.Obj.CleanupAsync();
}
services.AddSingleton<IHostedService>(new ShutdownHostedService { Obj = ... });
Однако разработчики приложений, конечно, могут добавлять свои собственные IHostedService
реализации, которые могут взаимодействовать с моей библиотекой. Вот почему важно, чтобы моя собственная реализация IHostedService
вызывалась последней. Но вот в чем проблема.
С введением ASP.NET Core 2.1 разработчики приложений могут выбирать между использованием нового Microsoft.Extensions.Hosting.Host
и (теперь устаревшего) Microsoft.AspNetCore.WebHost
. С WebHost
при завершении работы IHostedService
реализаций вызываются в порядке регистрации, тогда как с Host
IHostedService
реализации вызываются в противоположном порядке регистрации.
Это проблематично для меня, потому что мой размещенный сервис должен вызываться последним. Поскольку разработчики приложений могут использовать мой пакет интеграции в своем существующем приложении ASP.NET Core, они могут по-прежнему использовать WebHost
, поэтому важно поддерживать этот сценарий.
Вопрос. Каким будет надежный способ определить, в каком «режиме» работает приложение ASP.NET Core, чтобы я мог решить добавить свою размещенную службу в первую или последнюю очередь?
В качестве альтернативы, чтобы не попасть в ловушку проблемы XY, я открыт для совершенно разных решений, которые решают мою проблему реализации асинхронного отключения.
Примечание к IAsyncDisposable
:
Одно из решений, которое приходит на ум (как справедливо отмечает Ян в комментариях), состоит в том, чтобы добавить регистрацию IAsyncDisposable
Singleton к ServiceCollection
. Это позволило бы асинхронную очистку при завершении работы. К сожалению, из-за ограничений (объясненных здесь) мой пакет интеграции не может принять зависимость от Microsoft.Bcl.AsyncInterfaces
и, следовательно, не от IAsyncDisposable
. Это неприятная ситуация, которая, безусловно, усложняет дело. На самом деле, причина невозможности получить зависимость от IAsyncDisposable
— это причина, по которой я ищу альтернативные способы реализации кода асинхронного завершения работы.
IAsyncDisposable
, который изначально поддерживается в Core 3.0 и выше и имеет прокладку для более старых версий через пакетMicrosoft.Bcl.AsyncInterfaces
NuGet. Кроме того, спросите непосредственно в репозитории ASP.NET Core GitHub. - person Ian Kemp   schedule 08.12.2020IAsyncDisposable
неуместно (я должен был более четко указать это в своем вопросе).IAsyncDisposable
это как раз проблема, почему я в такой ситуации. Новая версия библиотеки, которую я разрабатываю, намеренно удаляет зависимость отMicrosoft.Bcl.AsyncInterfaces
, которая запрещает мне добавлять регистрациюIAsyncDisposable
в файлIServiceCollection
. - person Steven   schedule 08.12.2020IHostedService
, наводит меня на мысль, что это действительно не стоит вашего времени. - person Ian Kemp   schedule 08.12.2020IApplicationLifetime
либоApplicationStopping
, либоApplicaionStopped
. - person Nkosi   schedule 08.12.2020IHostLifetime
, но это также немного усложняет ситуацию, поскольку вам нужно поддерживать разные времена жизни… - person poke   schedule 08.12.2020CleanupAsync().GetAwaiter().GetResult()
из методаDispose
. Смотрите мой собственный ответ. - person Steven   schedule 08.12.2020IHostApplicationLifetime
кстати. - person poke   schedule 09.12.2020