Skip to content

Instantly share code, notes, and snippets.

@whyleee
Created December 13, 2019 10:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save whyleee/d1516471fce7a417dd68c4e40db765c4 to your computer and use it in GitHub Desktop.
Save whyleee/d1516471fce7a417dd68c4e40db765c4 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Routing;
using EPiServer;
using EPiServer.Core;
using EPiServer.Framework.Cache;
using EPiServer.Globalization;
using EPiServer.Web;
using EPiServer.Web.Routing;
using EPiServer.Web.Routing.Internal;
namespace Modules.Areas.WebCore.Business.Caching
{
public class CachedUrlResolver : DefaultUrlResolver
{
private readonly IContentLoader _contentLoader;
private readonly IContextModeResolver _contextMode;
private readonly LanguageResolver _languageResolver;
private readonly ISynchronizedObjectInstanceCache _cache;
private readonly IContentCacheKeyCreator _cacheKeyCreator;
public CachedUrlResolver(
RouteCollection routes,
IContentLoader contentLoader,
ISiteDefinitionRepository siteDefinitionRepository,
TemplateResolver templateResolver,
IPermanentLinkMapper permanentLinkMapper,
IContentLanguageSettingsHandler contentLanguageSettingsHandler,
IContextModeResolver contextMode,
LanguageResolver languageResolver,
ISynchronizedObjectInstanceCache cache,
IContentCacheKeyCreator cacheKeyCreator)
: base(routes, contentLoader, siteDefinitionRepository, templateResolver, permanentLinkMapper, contentLanguageSettingsHandler)
{
_contentLoader = contentLoader;
_contextMode = contextMode;
_languageResolver = languageResolver;
_cache = cache;
_cacheKeyCreator = cacheKeyCreator;
}
public override VirtualPathData GetVirtualPath(ContentReference contentLink, string language, VirtualPathArguments arguments)
{
if (ContentReference.IsNullOrEmpty(contentLink))
{
return null;
}
arguments = (arguments ?? new VirtualPathArguments());
var request = arguments.RequestContext?.HttpContext?.Request;
if (request == null && HttpContext.Current != null)
{
request = new HttpRequestWrapper(HttpContext.Current.Request);
}
var preferredLanguage = !string.IsNullOrEmpty(language) ? language : _languageResolver.GetPreferredCulture().Name;
var epslanguage = arguments.RouteValues?[RoutingConstants.LanguageQueryParameter];
var forceCanonicalRv = arguments.RouteValues?[RoutingConstants.ForceCanonicalKey];
var forceCanonical = arguments.ForceCanonical || (forceCanonicalRv != null && (bool)forceCanonicalRv);
var contextMode = arguments.ContextMode != ContextMode.Undefined ? arguments.ContextMode : _contextMode.CurrentMode;
var cacheKey = $"RW|Url|{contentLink}|{preferredLanguage}|{contextMode}|host:{request?.Url?.Host}|vt:{arguments.ValidateTemplate}|epsl:{epslanguage}|fc:{forceCanonical}|action:{arguments.Action}";
var result = (VirtualPathData) _cache.Get(cacheKey);
if (result != null)
{
return result;
}
result = base.GetVirtualPath(contentLink, language, arguments);
if (result == null)
{
return null;
}
var masterKeys = new List<string>
{
_cacheKeyCreator.RootKeyName
};
if (!ContentReference.IsNullOrEmpty(contentLink))
{
masterKeys.Add(_cacheKeyCreator.CreateCommonCacheKey(contentLink));
if (string.IsNullOrEmpty(contentLink.ProviderName))
{
var ancestorKeys = _contentLoader.GetAncestors(contentLink)
.Reverse()
.Skip(2)
.Select(c => _cacheKeyCreator.CreateCommonCacheKey(c.ContentLink))
.ToList();
masterKeys.AddRange(ancestorKeys);
}
}
_cache.Insert(cacheKey, result, new CacheEvictionPolicy(
TimeSpan.FromHours(1), CacheTimeoutType.Absolute, null, masterKeys));
return result;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment