I'm upgrading my site from Sitecore 8.1 to Sitecore 8.2, and one of the compile errors that I'm getting is

CS1503 Argument 3: cannot convert from 'long' to 'System.EventHandler'

As I'm looking into this, I think that I remember reading that Sitecore completely changed how the cache is working in 8.2, and therefore I will need to change my code as well. Can someone provide an overview of what kind of changes I'll need to make to my code so that I can run on 8.2?

Edit

This class is based on the Sitecore.Cachine.CustomCache class. Here's the code that I'm having problems with:

    public void SetObject(string key, object content)
    {
        base.SetObject(key, content, EstimateObjectSize(content));
    }

    private long EstimateObjectSize(object obj)
    {
        long size = 0;
        try
        {
            using (Stream s = new MemoryStream())
            {
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(s, obj);
                size = s.Length;
            }
        }
        catch(SerializationException)
        {
            // object cannot be serialized so just return 0
            size = 0;
        }
        return size;
    }

The code is complaining about the base.SetObject call (with the EstimateObjectSize) method. I understand that I need to change my object, and having read that document that Mark posted, I still am not sure what changes need to be done. It seems as if the SetObject method has changed from holding content to holding some sort of event, and I can't wrap my head around how this is supposed to work. I'm sorry for the vague/generic original post, I'll try to be more specific in the future.

Thanks for your help!

  • Sure, but this would end up a link-only answer. I literally just googled "sitecore 8.2 cache changes" and came up with doc.sitecore.net/sitecore_experience_platform/developing/…. – Mark Cassidy Sep 27 '16 at 23:15
  • 3
    I'm voting to close this question as off-topic because it invites a 1 link only answer; or is too broad/generic to solicit any good answers – Mark Cassidy Sep 27 '16 at 23:15
  • 2
    I actually have through experience with the cache changes specifically as my marketplace module makes heavy use of customized caches. I do think I could provide a detailed answer. However, I don't think I have enough information to go on. What part of the code is failing? Why do you think it's caches? If I can see a code snippet, I can work up a answer. – Pete Navarra Sep 28 '16 at 3:54
up vote 4 down vote accepted

Based on your code snippet above, and compared with what I'm doing with my custom caches, you don't have to call base.SetObject(). As long as you provide a long maxSize in the base constructor call, the CustomCache class will take care of the rest. One of the changes Sitecore made was removing the need to calculate the size of your cache object. The new cache provider will do that for you.

Here is a code snippet (below) from my Dynamic Sites Manager, where I'm creating a custom cache based off of CustomCache class, and updated for Sitecore 8.2.

I would just remove the need to call base.SetObject()

using System.Collections;
using Sitecore.Caching;
using Sitecore.SharedSource.DynamicSites.Utilities;
using Sitecore.Sites;
namespace Sitecore.SharedSource.DynamicSites.Caching
{
    internal class SiteCache : CustomCache
    {
        public SiteCache(long maxSize) : base(DynamicSiteSettings.CacheKey, maxSize)
        {
        }

        //AddSite
        public void AddSite(Site siteItem)
        {
            if (ContainsSite(siteItem))
            {
                RemoveSite(siteItem);
            }

            var cacheItem = new SiteCacheItem(siteItem);
            InnerCache.Add(siteItem.Name, cacheItem);
        }

        //GetSite
        public Site GetSite(string name)
        {
            if (!ContainsSite(name)) return null;
            return (Site)InnerCache.GetValue(name);
        }

        private void RemoveSite(Site siteItem)
        {
            if (ContainsSite(siteItem))
            {
                //Refresh Information
                InnerCache.Remove(siteItem.Name);
            }
        }

        //GetAllSites
        public SiteCollection GetAllSites()
        {
            return GetAllSites(InnerCache.GetCacheKeys());
        }

        //ContainsSite
        public bool ContainsSite(Site siteItem)
        {
            return InnerCache.ContainsKey(siteItem.Name);
        }

        private bool ContainsSite(string name)
        {
            return InnerCache.ContainsKey(name);
        }

        // Count
        public int Count()
        {
            return InnerCache.Count;
        }

        public SiteCollection GetAllSites([NotNull] IEnumerable orderedList)
        {
            var collection = new SiteCollection();

            foreach (string siteName in orderedList)
            {
                collection.Add(GetSite(siteName));
            }

            return collection;

        }
    }
}

To expand upon why you are seeing this, base.SetObject() was changed from 3 arguments to two, and then another overload was added to handle an event. This is why you are seeing the event handler.

using Sitecore.Data;
using Sitecore.Diagnostics;
using Sitecore.Diagnostics.PerformanceCounters;
using System;

namespace Sitecore.Caching.Generics
{
  public abstract class CustomCache<TKey>
  {
    ...
    protected void SetObject(TKey key, object value)
    {
      if (!this.Enabled)
        return;
      this.cache.Add(key, value);
    }

    protected void SetObject(TKey key, object value, EventHandler<EntryRemovedEventArgs<TKey>> removedHandler)
    {
      if (!this.Enabled)
        return;
      this.cache.Add(key, value, removedHandler);
    }
    ...
  }
}

Low-level API changes are too numerous to document here, but from a high level:

  • The CacheManager has now been abstracted to a BaseCacheManager, in line with many of the other Dependency Injection changes in 8.2.
  • The Cache class has been abstracted to an ICache, allowing for other cache implementations in the future (e.g. Redis).
  • Statics on the Cache class for finding/creating a cache are no longer present -- you must utilize the CacheManager.
  • The base cache implementation can now estimate object sizes itself, and all size arguments have been eliminated from the Add overloads on the cache. So above in your question, you can simply eliminate your third argument. The event handler it is looking for in your compiler error is an optional callback for when the object is removed from the cache.
  • If you really want to handle the size calculation yourself, there is the an ICacheSizeCalculationStrategy, which is set on a property of Cache<T>, but the setter appears to be private at this time. You would need to provide your own ICache implementation. But this really is overkill -- in most production deployments you'll be disabling cache size limitations anyway.

You can find more details on the changes in the Sitecore documentation.

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.