Разрешение мультитенантной информации из HttpContext и асинхронных вызовов

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

Это приложение использует OpenID Connect для аутентификации. Идея состоит в том, чтобы после успешной аутентификации пользователя найти соответствующего арендатора (т.е. TenantID) и сохранить TenantID в качестве претензии на HttpContext. Для любого последующего запроса я могу разрешить клиента из HttpContext и использовать его TenantID фильтровать EF-запросы. Что-то вроде этого

public class ClientService:IClientService
{
     public async Task<Client> GetClientInfo()
     {
          //NOTE: The framework will implicitly resolve the TenantID from HttpContext and make it available to the Service.

          return await _dbContext.Clients.Where(x=>x.TenantID = this.TenantID)
          .SingleOrDefaultAsync()
          .ConfigureAwait(false)
     }
}

а затем в контроллере

  public class ClientController
  {
     private readonly IClientService _service;

    public ClientController(IClientService service)
    {
       _service = service;
    }


    public async Task<ActionResult> Index()
    {
       var entity = await _service.GetClientInfo().ConfigureAwait(false);
       var model = MapEntityToModel(entity);
       return View(model);           
    }
 }

Обратите внимание на использование ConfigureAwait(false), (Есть несколько статей и ТАК обсуждений, почему мы должны использовать ConfigureAwait(false) чтобы избежать тупиков и лучшей производительности. Как этот MSDN)

Проблема из-за ConfigureAwait(false) HttpContext будет нулевым в ClientService

Одним из способов решения этой проблемы является получение TenantID в контроллере и передать его в качестве параметра

public async Task<ActionResult> Index()
{
   // get the tenantid that is stored in claims on HttpContext
   var tenantID = GetTenantIDFromHttpContext();
   var entity = await _service.GetClientInfo(tenantID).ConfigureAwait(false);
   var model = MapEntityToModel(entity);
   return View(model);           
}

Однако приложение будет иметь несколько сотен методов обслуживания, и каждый будет использовать TenantID для фильтрации запросов EF. Разрешить его в контроллере не представляется возможным.

Есть ли другие способы решения TenantID без необходимости идти на компромисс ConfigureAwait(false)

0 ответов

Другие вопросы по тегам