Сохранение/кэширование данных между запросами – общий подход

StackOverflow https://stackoverflow.com/questions/1263580

Вопрос

Я разрабатываю приложение Asp.net (MVC, но это не имеет особого значения).У меня есть собственный IHttpModule, который отвечает за PostAuthenticateRequest для изменения принципала и личности пользователя.

Я сохраняю UserID и UserName в файле cookie аутентификации при входе пользователя в систему.У меня есть IUser (реализованный слоем DAO и Business Objects, каждый со своими дополнительными членами), который мне нужен во всех классах Business Service.Когда пользователю что-то нужно, я должен предоставить экземпляр объекта IUser (обычно из уровня Business Objects), поэтому предоставления идентификатора из билета аутентификации недостаточно.

Итак, я думаю о том, как и где лучше всего было бы сохранить зарегистрированные данные пользователя IUser?

  1. Я не хочу каждый раз получать его из БД (на основе данных UserID билета аутентификации)
  2. Я не могу сохранить его в сеансе, так как мне нужно работать внутри PostAuthenticateRequest, где сеанс еще не готов.
  3. Я хочу, чтобы все функции были инкапсулированы в мой собственный IHttpModule.

Варианты, которые я вижу:

  • Кэш
  • печенье
  • (Сессия) - путем перехода от PostAuthenticateRequest к событию PostAcquireRequestState и изменения там принципала/идентичности, но я бы хотел избежать этого

Процессы, которые кажутся усложняющими ситуацию:

  1. Пользователь входит в систему, пользовательские данные извлекаются из БД и каким-то образом сохраняются для последующих запросов.
  2. Пользователь выходит из системы, пользовательские данные должны быть автоматически удалены с постоянного носителя.
  3. Пользователь меняет свой профиль, данные пользователя необходимо удалить и перечитать при следующем запросе из БД.

Я не хочу, чтобы все это автоматически обрабатывалось HttpModule (если возможно), чтобы исключить ошибки разработчика, которые забывают сбросить эти вещи.

Чего я также не хочу, так это писать/читать некоторые жестко запрограммированные переменные/ключи и манипулировать ими в других частях приложения.Это лишь создаст технический долг.

Вопросы

  1. Что ты предлагаешь?
  2. Как SO сохраняет пользовательские данные между запросами?
Это было полезно?

Решение

Учитывая ваши требования, я полагаю, что лучшим решением будет получить идентификатор из файла cookie и использовать его для индексации в Http-кэш (HttpContext.Current.Cache).

Если вы хотите сохранить доступ пользователей к нему, оберните Cache в объект UserCache.Объект может быть создан с помощью HttpModule и сохранен как (подождите...) синглтон в самом кеше или, что еще лучше, просто создан, когда необходимо извлечь его из http-кеша.Это будет зависеть от того, где вам нужно получить к нему доступ и доступен ли HttpContext.Current.Cache напрямую.Ленивая реализация приведена ниже.

Опять же, это для ясности, а не то, как я бы это реализовал.

public class UserCache
{
  public IUser GetUser(object userKey)
  {
    return HttpContext.Current.Cache[userKey];
  }

  public void AddUser(object userKey, IUser user)
  {
    /* this could pull the key from the user object as well. */
    HttpContext.Current.Cache.Add(/* add the object with key and a sliding expiration that is slightly greater than session timeout */);
  }

  public void ExpireUser(object userKey)
  {
    HttpContext.Current.Cache.Remove(userKey);
  }

  /* If you don't want to do SQL cache dependency */
  public void UpdateUser(object userKey, IUser user)
  {
    HttpContext.Current.Cache.Insert(/* ... */);
  }
}

Используя механизмы кэширования по умолчанию (или, что еще лучше, механизм кэширования, предоставляемый DI, чтобы вы не были привязаны к реализации), вы можете установить срок действия для автоматического удаления пользователей из кеша, как указано в комментарии.Вы можете настроить кэш так, чтобы он зависел от обновлений SQL-сервера, а также для обработки обновлений или вручную обновлять его как часть службы для сохранения изменений.

Доступна дополнительная информация о кэше по умолчанию. здесь.Дополнительная информация о зависимости кэша доступен здесь.

Я полагаю, что в самом HttpModule вы могли бы поволшебствовать в событии EndRequest, чтобы проверить, аутентифицирован ли запрос, а затем выйти из системы на основе файла cookie, но я не уверен, что это сработает, поскольку я никогда не пробовал это.Возможно, вы захотите взглянуть на Эта статья на MSDN от WAY еще в дни 1.1 и посмотрите, отвечает ли он на некоторые проблемы, которые вы пытаетесь решить.

Что касается архитектуры SO и того, как они это делают, я предполагаю, что они загружают ее при необходимости, потому что они постоянно хранят большую часть базы данных в оперативной памяти (http://highscalability.com/stack-overflow-architecture).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top