Кэширование объектов в EPiServer CMS 7.5 с зависимостями кеша

Я хотел бы сохранить небольшой список объектов и создать зависимость от стартовой страницы веб-сайта. Таким образом, принудительная аннулирование кеша при изменении начальной страницы. Это было легко сделать со старой реализацией кеша, которая теперь устарела.

В документации говорится, что я следует использовать класс CacheEvictionPolicy. Но я не могу понять, как настроить зависимости с этим классом.

Мой вопрос: как кэшировать объекты с зависимостями от содержимого EPiServer (IContent) в EPiServer 7.5 (без использования устаревших методов и включения функции сообщений о недействительности между веб-серверами)?


person maets    schedule 30.03.2015    source источник


Ответы (2)


Вы должны иметь возможность использовать DataFactoryCache.CreateDependency() для создания зависимостей кэша. Он поддерживает указание ContentReference в качестве параметра, например, ContentReference.StartPage для очистки записи кэша при обновлении начальной страницы.

Кроме того, большая часть этого (хотя и для EPiServer 6) по-прежнему актуальна: http://tedgustaf.com/blog/2010/5/cache-objects-in-episerver-with-page-dependencies/

Если я неправильно понимаю, чего вам нужно достичь?

Изменить: для EPiServer 7.5+ следует использовать CacheEvictionPolicy, например:

EPiServer.CacheManager.Insert(
                key,
                item,
                new CacheEvictionPolicy(
                    new List<string>() { DataFactoryCache.PageCommonCacheKey(dependencyLink) }
                )
            );
person Ted Nyberg    schedule 30.03.2015
comment
Все методы, использующие объект CacheDependency, устарели и вместо этого сообщают вам о вызове метода Insert(string key, object value, CacheEvictionPolicy evictionPolicy). Методы, принимающие экземпляр CacheDependency, нельзя использовать ни с чем, кроме HttpRuntime.Cache. Но будет ли так работать инвалидация кеша EPiServer между серверами? - person maets; 31.03.2015
comment
Я добавил пример кода CacheEvictionPolicy в свой первоначальный ответ, надеюсь, это поможет? Использование CacheManager позволит аннулировать кеш на кластерных серверах. - person Ted Nyberg; 31.03.2015
comment
Да. Что помогает. Я посмотрел с помощью рефлектора и увидел, что он действительно использует экземпляр ISynchronizedObjectInstanceCache из ServiceLocator. Но не следует ли считать использование класса CacheManager не лучшей практикой? На мой взгляд, сценарий очень похож на использование класса DataFactory вместо IContentRepository/IContentLoader. - person maets; 01.04.2015
comment
@maets Да, просто используйте IObjectInstanceCache вместо CacheManager, потому что последний является просто статической оболочкой. - person whyleee; 05.04.2015

Мне удалось решить это. Используя метод, найденный здесь.

Я создал простую реализацию, например (не потокобезопасную):

    private static ISynchronizedObjectInstanceCache _cacheInstance;
    public static ISynchronizedObjectInstanceCache CacheImplementation
    {
        get
        {
            return (_cacheInstance ?? (_cacheInstance = ServiceLocator.Current.GetInstance<ISynchronizedObjectInstanceCache>()));
        }
        set
        {
            _cacheInstance = value;
        }
    } 
    public IList<MyObject> GetCachedObjects()
    {
        if (_cachedObjects == null)
        {
            object value = CacheImplementation.Get("MyObjectsCacheKey");
            if (value == null)
            {
                // Lookup objects (the slow function that triggered the need for caching)
                _cachedObjects = LookupMyObjects();
                string currentLanguage = ContentLanguage.PreferredCulture.Name;

                // Create dependencies and add to cache
                List<string> cacheDependencyKeys = new List<string>();

                // Add dependency to the start page
                cacheDependencyKeys.Add(DataFactoryCache.PageLanguageCacheKey(ContentReference.StartPage, currentLanguage));

                // Add dependency to the pointed out startpoint of the lookup of "MyObjects" (if not null)
                // This will force a cache invalidation when the page itself or it's children are changed.
                if (CurrentPage.MyObjectsStartPoint != null)
                {
                    cacheDependencyKeys.Add(DataFactoryCache.PageLanguageCacheKey(CurrentPage.MyObjectsStartPoint, currentLanguage));
                    cacheDependencyKeys.Add(DataFactoryCache.ChildrenCacheKey(CurrentPage.MyObjectsStartPoint));
                }
                // Do insert into cache
                CacheImplementation.Insert("MyObjectsCacheKey", _cachedObjects, new CacheEvictionPolicy(cacheDependencyKeys.ToArray()));
            } else 
            {
                _cachedObjects = value as IList<MyObject>;    
            }
        }
        return _cachedObjects;
    } private IList<MyObject> _cachedObjects = null;

Изменить: изменен на ISynchronizedObjectInstanceCache вместо IObjectInstanceCache. Класс EPiServer "CacheManager" использует эту реализацию и должен работать с аннулированием кеша между серверами.

person maets    schedule 31.03.2015