This the CacheProvider I implemented:
namespace NopSolutions.NopCommerce.BusinessLogic.Caching {
public interface ICacheProvider {
T Get<T>(string key);
void Set(string key, object data, int cacheTime);
bool IsSet(string key);
void Invalidate(string key);
}
}
namespace NopSolutions.NopCommerce.BusinessLogic.Caching {
public class MemoryCacheProvider : ICacheProvider {
ObjectCache Cache { get { return MemoryCache.Default; } }
public T Get<T>(string key) {
return (T)Cache[key];
}
public void Set(string key, object data, int cacheTime) {
var policy = new CacheItemPolicy();
policy.AbsoluteExpiration = DateTime.Now + TimeSpan.FromMinutes(cacheTime);
Cache.Add(new CacheItem(key, data), policy);
}
public bool IsSet(string key) {
return (Cache.Contains(key));
}
public void Invalidate(string key) {
Cache.Remove(key);
}
}
}
You will need to add a reference to System.Runtime.Caching.
A sample usage:
private static ICacheProvider Cache { get { return new MemoryCacheProvider(); } }
/// <summary>
/// Gets all categories filtered by parent category identifier
/// </summary>
/// <param name="parentCategoryId">Parent category identifier</param>
/// <param name="showHidden">A value indicating whether to show hidden records</param>
/// <returns>Category collection</returns>
public static List<Category> GetAllCategoriesByParentCategoryId(int parentCategoryId,
bool showHidden)
{
string key = string.Format("nop.category.parent-{0}-{1}", parentCategoryId.ToString(), showHidden.ToString());
if (Cache.IsSet(key))
return Cache.Get<List<Category>>(key);
var context = ObjectContextHelper.CurrentObjectContext;
var query = from c in context.Categories
orderby c.DisplayOrder
where (showHidden || c.Published) &&
!c.Deleted &&
c.ParentCategoryId == parentCategoryId
select c;
var categories = query.ToList();
Cache.Set(key, categories, 30);
return categories;
}
This particular query isn't exactly slow to execute ( < 1ms) but it soon pays for itself.
On default.aspx this query is executed once (root categories)
On a root category page is it executed 3 times
On a sub category page it is executed 4 times
and so on
So even for a simple method like this, performance improvements can be made.
Of course the real benefit is going to be sorting the GetAllProducts method. Rather than pulling all products into cache (as someone suggested) I would prefer to see this refactored into simplified methods and us caching each collection individually. This allows your cache invalidation to be much more targeted.