Сохранение/кэширование данных между запросами – общий подход
-
13-09-2019 - |
Вопрос
Я разрабатываю приложение Asp.net (MVC, но это не имеет особого значения).У меня есть собственный IHttpModule, который отвечает за PostAuthenticateRequest для изменения принципала и личности пользователя.
Я сохраняю UserID и UserName в файле cookie аутентификации при входе пользователя в систему.У меня есть IUser (реализованный слоем DAO и Business Objects, каждый со своими дополнительными членами), который мне нужен во всех классах Business Service.Когда пользователю что-то нужно, я должен предоставить экземпляр объекта IUser (обычно из уровня Business Objects), поэтому предоставления идентификатора из билета аутентификации недостаточно.
Итак, я думаю о том, как и где лучше всего было бы сохранить зарегистрированные данные пользователя IUser?
- Я не хочу каждый раз получать его из БД (на основе данных UserID билета аутентификации)
- Я не могу сохранить его в сеансе, так как мне нужно работать внутри PostAuthenticateRequest, где сеанс еще не готов.
- Я хочу, чтобы все функции были инкапсулированы в мой собственный IHttpModule.
Варианты, которые я вижу:
- Кэш
- печенье
- (Сессия) - путем перехода от PostAuthenticateRequest к событию PostAcquireRequestState и изменения там принципала/идентичности, но я бы хотел избежать этого
Процессы, которые кажутся усложняющими ситуацию:
- Пользователь входит в систему, пользовательские данные извлекаются из БД и каким-то образом сохраняются для последующих запросов.
- Пользователь выходит из системы, пользовательские данные должны быть автоматически удалены с постоянного носителя.
- Пользователь меняет свой профиль, данные пользователя необходимо удалить и перечитать при следующем запросе из БД.
Я не хочу, чтобы все это автоматически обрабатывалось HttpModule (если возможно), чтобы исключить ошибки разработчика, которые забывают сбросить эти вещи.
Чего я также не хочу, так это писать/читать некоторые жестко запрограммированные переменные/ключи и манипулировать ими в других частях приложения.Это лишь создаст технический долг.
Вопросы
- Что ты предлагаешь?
- Как 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).