Мой взгляд на кэш в памяти
Я работал над некоторыми вещами, которые обрабатывали большой объем данных. Делая это, я понял, что большая часть этого никогда не меняется, или, по крайней мере, в течение определенного времени это не так.
Поэтому я подумал, что было бы полезно создать личный репозиторий кэша, конечно, это не ново, несколько недель назад я прочитал об этом в [посте] StackOverflow (https://nickcraver.com/blog/2019/08/06/stack-overflow-how-we-do-app-caching/#in-memory--redis-cache), написанном Ником Крейвером о том, как они управляют кешем приложений.
Кроме того, я всегда хотел разобраться с кешем, узнать, как он работает, его логику и как заставить его работать, так… почему бы и нет!
Поток
Вот краткий обзор того, как будет вести себя класс, который управляет кешем, когда пользователь запрашивает значение.
Реализация
Прежде чем мы начнем
Я знаю, я знаю. Есть System.Runtime.Caching, который обрабатывает кеш памяти. Но я решил создать его сам. Если вы хотите использовать этот класс, проверьте здесь инструкции.
###Элемент кэша
Первый шаг — создать класс, в котором будет храниться значение объекта и дата истечения срока действия. Вероятно, есть лучший способ сделать это, но я так подумал, так что вот:
[[[ТОК_6]]]
###Репозиторий кэша
Затем нам нужен класс, который обрабатывает объекты и где-то их сохраняет (как CacheItem). Мне нравится обрабатывать все данные/модели в классах, имеющих суфикс Repository, но это не обязательно, поэтому давайте создадим один для кэширования.
[[[ТОК_9]]]
На данный момент у нас есть статический словарь под названием Cache, в котором будут храниться все элементы. Помните, что это будет продолжаться только во время работы приложения, поэтому в этом учебнике есть кэширование в памяти.
Имейте в виду, что элемент Cache будет инициализирован после загрузки класса CacheRepository.
Единственный метод, доступный при вызове класса CacheRepository, — это GetOrSet(string key, Func<T> lookup, TimeSpan durationMinutes) для которого требуется три параметра:
key: идентификатор объекта для сохранения.lookup: функция обратного вызова в случае, если срок действия кеша истек или он равен нулю.durationMinutes: продолжительность в минутах, которая будет добавлена к текущему времени (в формате UTC).
Время кэширования
Теперь используйте наш репозиторий кэширования, чтобы получить откуда-нибудь данные.
Чтобы все это имело смысл, давайте создадим пример объекта с некоторыми свойствами, а затем репозиторий для извлечения и заполнения списка этого объекта.
public class User
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
public class UserRepository
{
public List<User> Get()
{
// Code to get users
}
}
Поскольку у нас есть метод заполнения списка User, давайте воспользуемся классом CacheRepository.
private UserRepository _userRepository = new UserRepository();
private List<User> _user;
public List<User> User
{
get
{
_user = CacheRepository.GetOrSet($"users", usersRepo.Get, TimeSpan.FromMinutes(10));
return _user;
}
}
И точно так же, каждый раз, когда вы обращаетесь к переменной User, она запрашивает у CacheRepository значение объекта, имеющего ключ users.
Если этот ключ существует, он проверит дату истечения срока действия. Если какое-либо из этих условий ложно, он будет использовать обратный вызов для установки значения (с помощью usersRepo.Get) объекта, сохранения его в кэше с датой истечения срока действия, установленной в DateTime.UtcNow + TimeSpan.FromMinutes(10) и возврата его.
