Thomas Krantz
Apr 6, 2012
  5257
(0 votes)

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.

Apr 06, 2012

Comments

valdis
valdis Apr 11, 2012 04:47 PM

Cool! Is first code snippet complete?

Thomas Krantz
Thomas Krantz Apr 12, 2012 11:44 PM

Not entirely.. missing some using-statements and a finishing } bracket it seems like. But it should work.

Please login to comment.
Latest blogs
Block type selection doesn't work

Imagine you're trying to create a new block in a specific content area. You click the "Create" link, expecting to see a CMS modal with a list of...

Damian Smutek | Nov 4, 2024 | Syndicated blog

.NET 8 FAQ

I have previously written about .NET compatibility in general and .NET 8 in particular, see blog posts here , here and here . With the end of suppo...

Magnus Rahl | Nov 4, 2024

Dynamic packages in Commerce Connect

In Optimizely Commerce Connect, you can group different items using packages and bundles. Package: A package has one or more versions of a product...

K Khan | Nov 1, 2024

Efficient Catalog Metadata Management and Product Updates Using DTOs in Optimizely Commerce

This post explores ways to manage and update catalog metadata in Optimizely Commerce by utilizing Data Transfer Objects (DTOs). DTOs provide a...

Sujit Senapati | Oct 31, 2024