Cache Tag Helpers in Optimizely 12

As developers, we always should look for opportunities to boost the performance of web applications. Caching is one of them. It can significantly improve our application load time and responsiveness and ASP.NET Core helps us with this by providing server-side caching using Caching Tag Helpers in views. In this blog post, I’ll share some code that I used while I was testing this new version. Those code snippets are self-explanatory and it will be easy to transport them to your projects. This was inspired by Scott Reed during the master class “Preparing for Optimizely CMS 12 and Commerce 14”. You can learn more about Cache Tag Helpers on the Microsoft documentation website.

public class ContentBlock : BlockData
{
    public virtual XhtmlString Content { get; set; }
}
public interface ICachedViewModel
{
    public string Version { get; set; }
}
public class ContentBlockViewModel : ICachedViewModel
{
    public string Version { get; set; }

    public XhtmlString Content { get; set; }
}
public abstract class CachedComponent<TBlockData> : PartialContentComponent<TBlockData>
    where TBlockData : BlockData
{
    protected T GetModel<T>(ContentReference reference, string key, Func<T> viewModelGenerationMethod)
        where T : class, ICachedViewModel
    {
        if (ContentReference.IsNullOrEmpty(reference))
        {
            return viewModelGenerationMethod.Invoke();
        }

        var groups = GetVisitorGroupIdsByCurrentUser(HttpContext);
        var repository = ServiceLocator.Current.GetInstance<IContentVersionRepository>();
        var lastReferenceId = repository.List(reference).First().ContentLink.WorkID;

        var version = reference.ID + "_" + lastReferenceId + "_" + groups;
        var cacheKey = $"block_viewmodel_{key}_{version}";

        var model = (T)CacheManager.Get(cacheKey);
        if (model != null)
        {
            return model;
        }

        model = viewModelGenerationMethod.Invoke();
        model.Version = version;

        var eviction = new CacheEvictionPolicy(TimeSpan.FromMinutes(60), CacheTimeoutType.Absolute);
        CacheManager.Insert(cacheKey, model, eviction);

        return model;
    }

    private string GetVisitorGroupIdsByCurrentUser(HttpContext httpContext)
    {
        var visitorGroupRepository = ServiceLocator.Current.GetInstance<IVisitorGroupRepository>();
        var visitorGroupRoleRepository = ServiceLocator.Current.GetInstance<IVisitorGroupRoleRepository>();

        var visitorGroupId = new List<string>();
        var user = httpContext.User;
        var visitorGroups = visitorGroupRepository.List();

        foreach (var visitorGroup in visitorGroups)
        {
            if (!visitorGroupRoleRepository.TryGetRole(visitorGroup.Name, out var virtualRoleObject))
            {
                continue;
            }

            if (virtualRoleObject.IsMatch(user, httpContext))
            {
                visitorGroupId.Add(visitorGroup.Id.ToString());
            }
        }

        return string.Join('|', visitorGroupId);
    }
}
public class ContentBlockComponent : CachedComponent<ContentBlock>
{
    protected override IViewComponentResult InvokeComponent(ContentBlock currentContent)
    {
        var contentBlock = (IContent)currentContent;

        var viewModel = GetModel(contentBlock.ContentLink, "base", () => GenerateViewModel(currentContent));

        return View("~/Features/Blocks/Content/ContentBlock.cshtml", viewModel);
    }

    private ContentBlockViewModel GenerateViewModel(ContentBlock currentBlock)
    {
        return new ContentBlockViewModel
        {
            Content = currentBlock.Content
        };
    }
}
@model Cms12.Features.Blocks.Content.ContentBlockViewModel

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<cache vary-by="@Model.Version">
    @Html.PropertyFor(x => x.Content)
    Current Date and Time: @DateTime.Now
</cache>

2 thoughts on “Cache Tag Helpers in Optimizely 12

  1. scottreednitecocom

    Thanks Francisco, if you check out the update I made yesterday to the exercise book I have shared the cache helpers that wrap up using the lazy loading method for the cache loading which is very useful 🙂

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s