Using a bit of System.Runtime.Caching with EPiServer
I have been poking around in System.Runtime.Caching that was introduced with .NET 4, and more specifically the MemoryCache.
The MemoryCache is virtually the same as the good old ASP.NET Cache, except it’s not dependent on System.Web which means you can use it without an HttpContext.
ChangeMonitors monitors changes in the state of data which a cache item depends on, and I’ve written a simple custom ChangeMonitor called PageChangeMonitor to monitor published EPiServer pages.
public class PageChangeMonitor : ChangeMonitor
{
private PageReference _pageLink;
public PageChangeMonitor(PageReference pageLink)
{
if(PageReference.IsNullOrEmpty(pageLink))
{
throw new ArgumentNullException("pageLink");
}
bool init = false;
try
{
_pageLink = pageLink;
DataFactory.Instance.PublishedPage += PublishedPage;
init = true;
}
finally
{
base.InitializationComplete();
if(!init)
{
base.Dispose();
}
}
}
void PublishedPage(object sender, PageEventArgs e)
{
if(e.PageLink.ID == _pageLink.ID)
{
OnChanged(e.PageLink);
}
}
protected override void Dispose(bool disposing)
{
DataFactory.Instance.PublishedPage -= PublishedPage;
}
public override string UniqueId
{
get { return Guid.NewGuid().ToString(); }
}
The PageChangeMonitor can be used to expire the cache item when a certain page is published. An example:
public string GetSomeDataForPage(PageData page)
{
var cacheKey = string.Format("some-data-{0}", page.PageLink.ID);
var cache = MemoryCache.Default;
var someData = (string) cache.Get(cacheKey);
if(someData != null)
{
// data was cached
return someData;
}
// data was not in cache. Either it has never been cached,
// or the PageChangeMonitor expired the cache when the page
// was published.
someData = DoSomeHeavyLiftingAndReturnData(page);
var policy = new CacheItemPolicy();
// create the PageChangeMonitor that should monitor the page
var monitor = new PageChangeMonitor(page.PageLink);
policy.ChangeMonitors.Add(monitor);
cache.Add(cacheKey, someData, policy);
return someData;
}
Enjoy! And remember – cache is king.
Cool! Is first code snippet complete?
Not entirely.. missing some using-statements and a finishing } bracket it seems like. But it should work.