Как новая задача в ASP.NET Core использует внедрение зависимостей? - PullRequest
0 голосов
/ 30 сентября 2018

Я использую среду выполнения ASP.NET CORE 2.0.5 для своего проекта WEBAPI.В моей реализации, когда приходит запрос, запускается новая задача, которая выполняет тяжелую работу и, в конце концов, делает запрос к веб-интерфейсу, где.В то же время я возвращаю успешный ответ своему абоненту.

Проблема в том, что, поскольку тяжелая работа занимает больше времени, я не могу использовать все службы DI, которые я настроил при запуске.класс, потому что исходный запрос уже был возвращен и все службы DI расположены.

Есть ли способ передать мою коллекцию IServiceCollection новой задаче или есть лучший подход к этому?

ОБНОВЛЕНИЕ:

Оказалось, что не все службы DI были утилизированы.Это был только этот:

services.AddTransient<HttpMessageHandler, HttpClientHandler>();

Эта строка для включения модульного теста.Без этого мой webapi работает нормально, но мой тестовый блок прерывается ...

Ответы [ 2 ]

0 голосов
/ 01 октября 2018

Asp.Net Core DI предоставляет 3 варианта для срока службы:

  • Переходный - Сервисы переходного периода жизни создаются каждый раз, когда их запрашивают.Они утилизируются вместе с сервисом, который его использует.
  • Scoped - Сервисы с ограниченным сроком действия создаются один раз для каждого запроса.Они располагаются вместе с областью действия.
  • Singleton - Службы времени жизни Singleton создаются при первом запросе.Они живут, пока приложение живо.

Таким образом, вы не можете перейти к фоновой задаче временного или ограниченного сервиса, поскольку она будет удалена после остановки основного потока.Но есть IServiceScopeFactory, который может создать для вас область при выполнении фоновой задачи, где вы можете безопасно разрешить свою зависимость, например:

private readonly IServiceScopeFactory _scopeFactory;

public Service(IServiceScopeFactory scopeFactory)
{
    _scopeFactory = scopeFactory;
}

public void RunBackgroundTask()
{    
    ThreadPool.QueueUserWorkItem(new WaitCallback(state => { 
        using (scope = _scopeFactory.CreateScope())
        {
            var dependencyService = scope.ServiceProvider.GetService(typeof(SecondService));
            // do your work here
        }));
    }
}
0 голосов
/ 30 сентября 2018

Поскольку зависимости располагаются для каждого запроса, лучшим подходом будет использование фоновой задачи для части «тяжелой работы».

Когда вы получите запрос, вы можете как-то сохранить данные (один из подходов - использовать базу данных) и после этого вернуть ответ вызывающей стороне.Затем вы можете использовать фоновую задачу самостоятельно.Фоновая задача будет периодически проверять, сохранены ли какие-либо запросы, и если да, она может выполнить «тяжелую работу», отправить запрос и очистить сохраненный запрос.

...