Кэширование с MemoryCache

Кэширование позволяет сохранять данные для последующего быстрого доступа к ним в случае необходимости. Использование возможностей кэширования способно увеличить производительность приложения, написанного на ASP.NET, так как число обращений к источникам данных (к тем же БД) существенно уменьшается. Наибольшую эффективность кэширование демонстрирует, когда на web-странице есть некоторые элементы, данные которых меняются редко либо меняются через какой-нибудь промежуток времени.

Наиболее простой способ кэширования в ASP.NET Core -- это использование объекта Microsoft.Extensions.Caching.Memory.IMemoryCache -- он предоставляет возможность сохранять данные в кэше на сервере.

Рассматривать механизм кэширования лучше всего на простом примере. Давайте представим, что необходимо кэшировать профиль пользователя либо информацию о пользователе, которая может долго не меняться. Для начала следует создать проект ASP.NET Core по типу Web Application (Model-View-Controller). Назовем его CachingMVC. Взаимодействие с БД будет происходить через Entity Framework.

Сначала следует добавить в проект в папку Models класс User, который нужен для описания используемых данных:

Чтобы обеспечить взаимодействие с MS SQL Server через Entity Framework надо добавить в проект через Nuget специальный пакет Microsoft.EntityFrameworkCore.SqlServer. А потом добавить в папку Models класс контекста данных под названием ApplicationContext:

Для обеспечения взаимодействия с контекстом и базой данных надо создать специальный сервис. Тут сначала добавляем в проект папку Services, а непосредственно в ней определяем новый класс UserService:

Через встроенный механизм по внедрению зависимостей этот сервис станет получать контекст данных и использовать его в целях взаимодействия с БД. Вдобавок к этому, класс реализует логику кэширования.

Кроме того, через механизм внедрения зависимостей в конструкторе у нас есть возможность получить объект кэша IMemoryCache. Используя методы интерфейса IMemoryCache, появляется возможность этим кэшем управлять:

  • bool TryGetValue(object key, out object value): для получения элемента по ключу key. Если успех, то параметр value заполнится полученным элементом, а метод вернет true;
  • object Get(object key): это дополнительный метод расширения. Получает по ключу key элемент, возвращая его;
  • void Remove(object key): для удаления из кэша элемента по ключу key;
  • object Set(object key, object value, MemoryCacheEntryOptions options): для добавления в кэш элемента с ключом key и значением value. Применяются опции кэширования MemoryCacheEntryOptions

Если говорить по сути, то встроенная реализация интерфейса IMemoryCache представляет собой класс MemoryCache, используемый по дефолту -- он инкапсулирует все объекты кэша в качестве словаря Dictionary.

У нас кэширование имплементируется в 2-х случаях: в случае получения объекта по id из базы данных и при добавлении этого объекта.

Также стоит отметить, что при добавлении объект сначала добавляется в БД, и, если добавление успешно, то также добавляется и в кэш:

Идем дальше: при сохранении объекта в кэше в виде его ключа выступает не что иное, как значение свойства Id. А посредством параметра AbsoluteExpirationRelativeToNow устанавливается время кэширования -- в нашем случае это 5 минут.

При получении объекта по id мы сначала пробуем обнаружить данный объект в кэше, и, если там его нет, он извлекается из БД, а потом добавляется в кэш.

Если же ключ в кэше был обнаружен, тогда в объект user будет передано извлекаемое из кэша значение, причем метод TryGetValue() вернет true. Чтобы установить время кэширования, используется альтернативный способ -- метод SetAbsoluteExpiration, который тоже устанавливает 5 мин.

В результате на выходе будет следующая структура проекта:

Далее надо будет зарегистрировать сервисы кэширования и entity framework, а также задействовать компонент middleware в классе Startup:

Но прежде всего, чтобы добавить возможность кэширования, следует добавить сервис в методе ConfigureServices():

То есть можно сказать, что данный сервис устанавливает зависимость для IMemoryCache, так как создается объект синглтон:

Теперь в классе контроллера HomeController определяем следующий код:

По итогу при 1-м обращении к программному приложению данные станут извлекаться из БД и сохраняться в кэш. При дальнейших обращениях в пределах установленного времени кэширования (5 минут) данные станут извлекаться уже из кэша:

По материалам https://metanit.com/.