Странный дизайн aspnetcore и параметры scope
От: Слава  
Дата: 08.01.22 02:26
Оценка:
Как передать параметры, контекст в scope, созданный стандартным service provider в aspnetcore?

(тут ничего нельзя передать вообще)
using var scope = serviceProvider.CreateScope();


У меня есть тест DI для веб-сервиса aspnetcore. Мне потребовалось имитировать запросы от разных тенантов, чтобы проверить правильность подгрузки всей конфигурации для каждого тенанта.

Сервисы, предоставляющие конфигурацию тенанта, берут данные из сервиса с текущим юзером и тенантом, а этот сервис получает данные из HttpContext, полученный через IHttpContextAccessor (который делается доступным в контейнере DI через startup AddHttpContextAccessor)

Для каждого тенанта нужен отдельный scope, как оно и делается в aspnetcore — на каждый входящий запрос есть отдельный scope.

Только вот когда я создаю этот scope, я не могу в него передать вообще ничего, он просто создаётся — и всё, и внутри него можно запрашивать сервисы у контейнера DI, добавить ничего нельзя.

Мне стало интересно, а как же сам aspnetcore передаёт в очередной scope этот самый HttpContext, ведь если у scope нет никаких параметров, то как это сделать-то?

А вот как, оказывается:
private static AsyncLocal<HttpContextHolder> _httpContextCurrent = new AsyncLocal<HttpContextHolder>();
...
 _httpContextCurrent.Value?.Context;

Впервые слышу про AsyncLocal, иду про него читать: "AsyncLocal<T> represents "ambient" data that is local to a given asynchronous control flow, such as an async method" (исходник https://referencesource.microsoft.com/#mscorlib/system/threading/asynclocal.cs )

Мда. То есть, это как thread local, только в контексте async, потому что в асинхронном окружении в одном потоке исполнения треды могут быть разными в разное время.

Мне одному кажется, что это какой-то несколько странноватый способ передачи контекста, через подобие thread local? А по-другому что, никак?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.