Иногда нам нужно загрузить, вычислить или разрешить значение более одного раза в запросе. Возможно, вашему сайту нужно получить значение, загрузив стартовую страницу, приняв ContentReference
value, загружая это содержимое, а затем возвращая из него значение свойства. Или, может быть, вам нужно получить и показать имя текущего клиента более чем в одном месте.
Почти весь контент Optimizely кэшируется внутри и загружается быстро. Но все же, если мы выполняем загрузку и преобразование более одного раза за запрос, может быть полезно кратковременно кэшировать его (хотя бы на время жизни текущего запроса).
Optimizely CMS имеет менее известный класс, называемый ContextCache
(существует в EPiServer.Framework
пространство имен). Его можно внедрить в любой класс, и он содержит словарь, который существует на протяжении всего времени существования текущего запроса. Когда запрос выполнен, содержимое удаляется (хотя и не удаляется).
Optimizely CMS использует его внутри для таких вещей, как разрешение текущего определения сайта или сопоставление групп посетителей. Это примеры значений, которые:
- Тяжело решить или вычислить
- Может быть получен много раз для одного запроса
- Не меняется при повторных вызовах в одном и том же запросе
Конечно, мы можем сделать подобные интерполяционные таблицы в классах самостоятельно. Но этот является потокобезопасным и может быть заменен в сценариях модульного тестирования.
Практический пример
Сайт может отображать имя клиента как в верхнем, так и в нижнем колонтитуле, а также в коде отслеживания. Простая реализация может выглядеть так:
using EPiServer.Framework;
using Mediachase.Commerce.Customers;namespace DemoSite.Customers;
public class CustomerService
{
private const string CustomerNameCacheKey = "CustomerName";
private readonly ContextCache _contextCache;public CustomerService(ContextCache contextCache) => _contextCache = contextCache;
public string GetCustomerNameDirect() => CustomerContext.Current.CurrentContactName;
public string GetCustomerNameCached()
{
var customerName = _contextCache[CustomerNameCacheKey] as string;
if (customerName == null)
{
customerName = CustomerContext.Current.CurrentContactName;
_contextCache[CustomerNameCacheKey] = customerName;
}return customerName;
}
}
В первом методе GetCustomerNameDirect
метод всегда вызывает CustomerContext
, который обращается к кешу и возвращает объект. Только тогда мы сможем получить значение имени. Если он вызывается три раза, то он делает три вызова CustomerContext
.
Во втором методе GetCustomerNameCached
метод вызывает только CustomerContext
первый раз. После этого имя клиента загружается только из ContextCache
. При обновлении страницы все начинается заново.
Другим примером может быть сайт Commerce с несколькими магазинами, где каждый сайт использует свой собственный каталог Commerce. Для разрешения текущего каталога из свойства начальной страницы необходимо выполнить две операции загрузки содержимого. И это, возможно, придется выполнять несколько раз за запрос. Таким образом, это был бы кандидат на ContextCache
.
Для этого есть много других вариантов использования. Но попробуйте кэшировать только простые значения в this.
Знаете ли вы какие-либо другие скрытые, но полезные классы во фреймворке Optimizely?