Bust Cache on Block Publish

Howdy!

This week I wanted to cache a model quite hard in the object cache. The trouble was that the content that I used for building the model was blocks in a content area. When adding or removing blocks from the area we could bust the cache by adding a dependency to the generated content cache key. In our case that was the start page, so using IContentCacheKeyCreator and generating a key for ContentReference.StartPage we get this behavior. Fantastic!

How about updating existing items in the content area? We would also like to bust the cache when editors make such updates. In our case, the block type is specific to a particular usage and content area. This allowed us to cut some corners that may not be applicable for more generic types and use cases.

In our case we could simply allow the cache to be busted upon publishing a particular block type. The property of the marker interface is of type string, but could as well have been an array of strings.

public interface IObjectCacheBuster
{
  string BustCacheKey { get; }
}
[InitializableModule]
[ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
public class PublishEventInitializationModule : IInitializableModule
{
  public void Initialize(InitializationEngine context)
  {
    var contentEvents = ServiceLocator.Current.GetInstance<IContentEvents>();
    contentEvents.PublishingContent += ContentEvents_PublishingContent;
  }

  private void ContentEvents_PublishingContent(object sender, EPiServer.ContentEventArgs e)
  {
    if (e.Content is IObjectCacheBuster cacheBuster)
    {
      var objectCache = ServiceLocator.Current.GetInstance<ISynchronizedObjectInstanceCache>();
      objectCache.Remove(cacheBuster.BustCacheKeyOnPublish);
    }
  }
}

A quick solution that works well for us and keeps the rendered view in sync with the setup in Episerver.

Cheers!