From 23bb0e3ac37a74d077e75c2b358a007579ede8cc Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Sat, 16 Mar 2013 08:47:55 +0600 Subject: [PATCH] Fixes: #U4-1930, #U4-1928, #U4-1929 - addes ContentTypeCacheRefresher to ensure that content type cache is cleared in load balanced scenarios. Cleans up a bit of code too. --- src/Umbraco.Core/Cache/CacheKeys.cs | 9 ++ src/Umbraco.Core/CacheHelper.cs | 16 +++ .../Cache/CacheRefresherEventHandler.cs | 42 +++++- .../Cache/ContentTypeCacheRefresher.cs | 101 +++++++++++++ src/Umbraco.Web/Cache/DistributedCache.cs | 1 + .../Cache/DistributedCacheExtensions.cs | 26 ++++ src/Umbraco.Web/Umbraco.Web.csproj | 1 + .../controls/ContentTypeControlNew.ascx.cs | 7 - src/umbraco.cms/businesslogic/ContentType.cs | 136 ++++++++---------- .../businesslogic/language/Language.cs | 8 +- .../propertytype/propertytype.cs | 43 +++--- 11 files changed, 270 insertions(+), 120 deletions(-) create mode 100644 src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs diff --git a/src/Umbraco.Core/Cache/CacheKeys.cs b/src/Umbraco.Core/Cache/CacheKeys.cs index 570c44f75d..310d860c50 100644 --- a/src/Umbraco.Core/Cache/CacheKeys.cs +++ b/src/Umbraco.Core/Cache/CacheKeys.cs @@ -21,5 +21,14 @@ namespace Umbraco.Core.Cache public const string TemplateCacheKey = "template"; public const string UserCacheKey = "UmbracoUser"; + + public const string ContentTypeCacheKey = "UmbracoContentType"; + + public const string ContentTypePropertiesCacheKey = "ContentType_PropertyTypes_Content:"; + + public const string PropertyTypeCacheKey = "UmbracoPropertyTypeCache"; + + //NOTE: I'm pretty sure we don't cache anything with this key anymore + internal const string PropertyTypeTabCacheKey = "Tab_PropertyTypes_Content:"; } } \ No newline at end of file diff --git a/src/Umbraco.Core/CacheHelper.cs b/src/Umbraco.Core/CacheHelper.cs index 8d52951584..8943d27a22 100644 --- a/src/Umbraco.Core/CacheHelper.cs +++ b/src/Umbraco.Core/CacheHelper.cs @@ -3,6 +3,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using System.Web; using System.Web.Caching; using Umbraco.Core.Logging; @@ -124,6 +125,21 @@ namespace Umbraco.Core } } + /// + /// Clears all cache items that have a key that matches the regular expression + /// + /// + public void ClearCacheByKeyExpression(string regexString) + { + foreach (DictionaryEntry c in _cache) + { + if (c.Key is string && Regex.IsMatch(((string)c.Key), regexString)) + { + ClearCacheItem((string)c.Key); + } + } + } + /// /// Returns a cache item by key, does not update the cache if it isn't there. /// diff --git a/src/Umbraco.Web/Cache/CacheRefresherEventHandler.cs b/src/Umbraco.Web/Cache/CacheRefresherEventHandler.cs index 3037ccd5c1..968d9a5804 100644 --- a/src/Umbraco.Web/Cache/CacheRefresherEventHandler.cs +++ b/src/Umbraco.Web/Cache/CacheRefresherEventHandler.cs @@ -1,12 +1,15 @@ -using Umbraco.Core; +using System.Collections.Generic; +using Umbraco.Core; +using Umbraco.Core.Cache; +using Umbraco.Core.Models; using Umbraco.Core.Services; using umbraco; using umbraco.BusinessLogic; using umbraco.cms.businesslogic; -using umbraco.cms.businesslogic.macro; using umbraco.cms.businesslogic.member; using System.Linq; -using umbraco.cms.businesslogic.template; +using Macro = umbraco.cms.businesslogic.macro.Macro; +using Template = umbraco.cms.businesslogic.template.Template; namespace Umbraco.Web.Cache { @@ -25,8 +28,13 @@ namespace Umbraco.Web.Cache //NOTE: These are 'special' event handlers that will only clear cache for items on the current server // that is because this event will fire based on a distributed cache call, meaning this event fires on // all servers based on the distributed cache call for updating content. - content.AfterUpdateDocumentCache += content_AfterUpdateDocumentCache; - content.AfterClearDocumentCache += content_AfterClearDocumentCache; + content.AfterUpdateDocumentCache += ContentAfterUpdateDocumentCache; + content.AfterClearDocumentCache += ContentAfterClearDocumentCache; + + //Bind to content type events + + ContentTypeService.SavedContentType += ContentTypeServiceSavedContentType; + ContentTypeService.SavedMediaType += ContentTypeServiceSavedMediaType; //Bind to user events @@ -59,12 +67,32 @@ namespace Umbraco.Web.Cache MediaService.Trashing += MediaServiceTrashing; } + /// + /// Fires when a media type is saved + /// + /// + /// + static void ContentTypeServiceSavedMediaType(IContentTypeService sender, Core.Events.SaveEventArgs e) + { + e.SavedEntities.ForEach(x => DistributedCache.Instance.RemoveMediaTypeCache(x)); + } + + /// + /// Fires when a content type is saved + /// + /// + /// + static void ContentTypeServiceSavedContentType(IContentTypeService sender, Core.Events.SaveEventArgs e) + { + e.SavedEntities.ForEach(x => DistributedCache.Instance.RemoveContentTypeCache(x)); + } + /// /// Fires after the document cache has been cleared for a particular document /// /// /// - void content_AfterClearDocumentCache(global::umbraco.cms.businesslogic.web.Document sender, DocumentCacheEventArgs e) + static void ContentAfterClearDocumentCache(global::umbraco.cms.businesslogic.web.Document sender, DocumentCacheEventArgs e) { DistributedCache.Instance.ClearAllMacroCacheOnCurrentServer(); DistributedCache.Instance.ClearXsltCacheOnCurrentServer(); @@ -75,7 +103,7 @@ namespace Umbraco.Web.Cache /// /// /// - void content_AfterUpdateDocumentCache(global::umbraco.cms.businesslogic.web.Document sender, DocumentCacheEventArgs e) + static void ContentAfterUpdateDocumentCache(global::umbraco.cms.businesslogic.web.Document sender, DocumentCacheEventArgs e) { DistributedCache.Instance.ClearAllMacroCacheOnCurrentServer(); DistributedCache.Instance.ClearXsltCacheOnCurrentServer(); diff --git a/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs b/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs new file mode 100644 index 0000000000..9b9c52e6c5 --- /dev/null +++ b/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Umbraco.Core; +using Umbraco.Core.Cache; +using Umbraco.Core.Models; +using Umbraco.Core.Persistence.Caching; + +namespace Umbraco.Web.Cache +{ + public class ContentTypeCacheRefresher : ICacheRefresher, ICacheRefresher + { + public Guid UniqueIdentifier + { + get { return new Guid(DistributedCache.ContentTypeCacheRefresherId); } + } + public string Name + { + get { return "ContentTypeCacheRefresher"; } + } + + public void RefreshAll() + { + //all property type cache + ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch(CacheKeys.PropertyTypeCacheKey); + //all content type property cache + ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch(CacheKeys.ContentTypePropertiesCacheKey); + } + + public void Refresh(int id) + { + ClearContentTypeCache(id); + } + + public void Remove(int id) + { + ClearContentTypeCache(id); + } + + public void Refresh(Guid id) + { + } + + public void Refresh(IContentType instance) + { + ClearContentTypeCache(instance); + } + + public void Remove(IContentType instance) + { + ClearContentTypeCache(instance); + } + + public void Refresh(IMediaType instance) + { + ClearContentTypeCache(instance); + } + + public void Remove(IMediaType instance) + { + ClearContentTypeCache(instance); + } + + private static void ClearContentTypeCache(params IContentTypeBase[] contentTypes) + { + contentTypes.ForEach(contentType => + { + //clears the cache for each property type associated with the content type + foreach (var p in contentType.PropertyTypes) + { + ApplicationContext.Current.ApplicationCache.ClearCacheItem(CacheKeys.PropertyTypeCacheKey + p.Id); + } + //clears the cache for all tabs + var regexMatch = string.Format("{0}_{1}_{2}", CacheKeys.PropertyTypeTabCacheKey, @"\d+", contentType.Id); + ApplicationContext.Current.ApplicationCache.ClearCacheByKeyExpression(regexMatch); + //clears the cache associated with the content type properties collection + ApplicationContext.Current.ApplicationCache.ClearCacheItem(CacheKeys.ContentTypePropertiesCacheKey + contentType.Id); + //clears the dictionary object cache of the legacy ContentType + global::umbraco.cms.businesslogic.ContentType.RemoveFromDataTypeCache(contentType.Alias); + }); + if (contentTypes.Any()) + { + InMemoryCacheProvider.Current.Clear(); + RuntimeCacheProvider.Current.Clear(); + } + } + + private static void ClearContentTypeCache(params int[] ids) + { + ClearContentTypeCache( + ids.Select( + x => + ApplicationContext.Current.Services.ContentTypeService.GetContentType(x) as IContentTypeBase) + .WhereNotNull() + .ToArray()); + } + + + } +} diff --git a/src/Umbraco.Web/Cache/DistributedCache.cs b/src/Umbraco.Web/Cache/DistributedCache.cs index 02146aa7f4..7b47b7371e 100644 --- a/src/Umbraco.Web/Cache/DistributedCache.cs +++ b/src/Umbraco.Web/Cache/DistributedCache.cs @@ -36,6 +36,7 @@ namespace Umbraco.Web.Cache public const string MediaCacheRefresherId = "B29286DD-2D40-4DDB-B325-681226589FEC"; public const string MacroCacheRefresherId = "7B1E683C-5F34-43dd-803D-9699EA1E98CA"; public const string UserCacheRefresherId = "E057AF6D-2EE6-41F4-8045-3694010F0AA6"; + public const string ContentTypeCacheRefresherId = "6902E22C-9C10-483C-91F3-66B7CAE9E2F5"; #endregion diff --git a/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs b/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs index 989ddd5355..e108c3d5cd 100644 --- a/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs +++ b/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs @@ -210,6 +210,32 @@ namespace Umbraco.Web.Cache } } + /// + /// Remove all cache for a given content type + /// + /// + /// + public static void RemoveContentTypeCache(this DistributedCache dc, IContentType contentType) + { + if (contentType != null) + { + dc.Remove(new Guid(DistributedCache.ContentTypeCacheRefresherId), x => x.Id, contentType); + } + } + + /// + /// Remove all cache for a given media type + /// + /// + /// + public static void RemoveMediaTypeCache(this DistributedCache dc, IMediaType mediaType) + { + if (mediaType != null) + { + dc.Remove(new Guid(DistributedCache.ContentTypeCacheRefresherId), x => x.Id, mediaType); + } + } + /// /// Clears the cache for all macros on the current server /// diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 3ca5d86f87..d0069ddd70 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -263,6 +263,7 @@ + diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentTypeControlNew.ascx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentTypeControlNew.ascx.cs index 770a27717f..39283f1a7a 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentTypeControlNew.ascx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentTypeControlNew.ascx.cs @@ -698,13 +698,6 @@ jQuery(document).ready(function() {{ refreshDropDowns(); }}); //} } } - - //Is only called to flush cache since gpw.PropertyType.Save() isn't called - // clear local cache - cms.businesslogic.cache.Cache.ClearCacheItem("UmbracoPropertyTypeCache" + gpw.PropertyType.Id); - // clear cache in ContentType - cms.businesslogic.cache.Cache.ClearCacheItem("ContentType_PropertyTypes_Content:" + contentTypeItem.Id); - _contentType.ClearVirtualTabs(); } //Update the SortOrder of the PropertyTypes diff --git a/src/umbraco.cms/businesslogic/ContentType.cs b/src/umbraco.cms/businesslogic/ContentType.cs index f5132faed7..c025ef35c2 100644 --- a/src/umbraco.cms/businesslogic/ContentType.cs +++ b/src/umbraco.cms/businesslogic/ContentType.cs @@ -5,6 +5,7 @@ using System.Threading; using System.Runtime.CompilerServices; using System.Linq; using Umbraco.Core; +using Umbraco.Core.Cache; using Umbraco.Core.Models; using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence.Caching; @@ -89,9 +90,7 @@ namespace umbraco.cms.businesslogic allowAtRoot, isContainer, Alias,icon,thumbnail,description FROM umbracoNode INNER JOIN cmsContentType ON umbracoNode.id = cmsContentType.nodeId WHERE nodeObjectType = @nodeObjectType"; - - private static readonly object m_Locker = new object(); - + #endregion #region Static Methods @@ -185,32 +184,10 @@ namespace umbraco.cms.businesslogic /// public static ContentType GetContentType(int id) { - return Cache.GetCacheItem(string.Format("UmbracoContentType{0}", id.ToString()), - m_Locker, - TimeSpan.FromMinutes(30), - delegate - { - return new ContentType(id); - }); - } - - /// - /// If true, this instance uses default umbraco data only. - /// - /// The ct. - /// - private static bool usesUmbracoDataOnly(ContentType ct) - { - bool retVal = true; - foreach (PropertyType pt in ct.PropertyTypes) - { - if (!DataTypeDefinition.IsDefaultData(pt.DataTypeDefinition.DataType.Data)) - { - retVal = false; - break; - } - } - return retVal; + return ApplicationContext.Current.ApplicationCache.GetCacheItem + (string.Format("UmbracoContentType{0}", id.ToString()), + TimeSpan.FromMinutes(30), + () => new ContentType(id)); } // This is needed, because the Tab class is protected and as such it's not possible for @@ -219,6 +196,7 @@ namespace umbraco.cms.businesslogic /// Flushes the tab cache. /// /// The tab id. + [Obsolete("Tab cache is flushed automatically by Umbraco when a content type changes")] public static void FlushTabCache(int TabId, int ContentTypeId) { Tab.FlushCache(TabId, ContentTypeId); @@ -539,46 +517,47 @@ namespace umbraco.cms.businesslogic { get { - string cacheKey = GetPropertiesCacheKey(); + var cacheKey = GetPropertiesCacheKey(); - return Cache.GetCacheItem>(cacheKey, propertyTypesCacheSyncLock, + return ApplicationContext.Current.ApplicationCache.GetCacheItem( + cacheKey, TimeSpan.FromMinutes(15), - delegate - { - //MCH NOTE: For the timing being I have changed this to a dictionary to ensure that property types - //aren't added multiple times through the MasterContentType structure, because each level loads - //its own + inherited property types, which is wrong. Once we are able to fully switch to the new api - //this should no longer be a problem as the composition always contains a correct list of property types. - var result = new Dictionary(); - using (IRecordsReader dr = - SqlHelper.ExecuteReader( - "select id from cmsPropertyType where contentTypeId = @ctId order by sortOrder", - SqlHelper.CreateParameter("@ctId", Id))) + () => { - while (dr.Read()) + //MCH NOTE: For the timing being I have changed this to a dictionary to ensure that property types + //aren't added multiple times through the MasterContentType structure, because each level loads + //its own + inherited property types, which is wrong. Once we are able to fully switch to the new api + //this should no longer be a problem as the composition always contains a correct list of property types. + var result = new Dictionary(); + using (IRecordsReader dr = + SqlHelper.ExecuteReader( + "select id from cmsPropertyType where contentTypeId = @ctId order by sortOrder", + SqlHelper.CreateParameter("@ctId", Id))) { - int id = dr.GetInt("id"); - PropertyType pt = PropertyType.GetPropertyType(id); - if (pt != null) - result.Add(pt.Id, pt); - } - } - - // Get Property Types from the master content type - if (MasterContentTypes.Count > 0) - { - foreach (var mct in MasterContentTypes) - { - var pts = ContentType.GetContentType(mct).PropertyTypes; - foreach (PropertyType pt in pts) + while (dr.Read()) { - if(result.ContainsKey(pt.Id) == false) + int id = dr.GetInt("id"); + PropertyType pt = PropertyType.GetPropertyType(id); + if (pt != null) result.Add(pt.Id, pt); } } - } - return result.Select(x => x.Value).ToList(); - }); + + // Get Property Types from the master content type + if (MasterContentTypes.Count > 0) + { + foreach (var mct in MasterContentTypes) + { + var pts = ContentType.GetContentType(mct).PropertyTypes; + foreach (PropertyType pt in pts) + { + if (result.ContainsKey(pt.Id) == false) + result.Add(pt.Id, pt); + } + } + } + return result.Select(x => x.Value).ToList(); + }); } } @@ -838,9 +817,6 @@ namespace umbraco.cms.businesslogic public override void Save() { base.Save(); - - // Remove from all doctypes from cache - FlushAllFromCache(); } /// @@ -1127,15 +1103,15 @@ namespace umbraco.cms.businesslogic /// /// Flushes the cache. /// - /// The id. + /// The id. public static void FlushFromCache(int id) { //Ensure that MediaTypes are reloaded from db by clearing cache InMemoryCacheProvider.Current.Clear(); - ContentType ct = new ContentType(id); - Cache.ClearCacheItem(string.Format("UmbracoContentType{0}", id)); - Cache.ClearCacheItem(ct.GetPropertiesCacheKey()); + var ct = new ContentType(id); + ApplicationContext.Current.ApplicationCache.ClearCacheItem(string.Format("{0}{1}", CacheKeys.ContentTypeCacheKey, id)); + ApplicationContext.Current.ApplicationCache.ClearCacheItem(ct.GetPropertiesCacheKey()); ct.ClearVirtualTabs(); //clear the content type from the property datatype cache used by razor @@ -1156,10 +1132,11 @@ namespace umbraco.cms.businesslogic } } + [Obsolete("The content type cache is automatically cleared by Umbraco when a content type is saved")] protected internal void FlushAllFromCache() { - Cache.ClearCacheByKeySearch("UmbracoContentType"); - Cache.ClearCacheByKeySearch("ContentType_PropertyTypes_Content"); + ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch(CacheKeys.ContentTypeCacheKey); + ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch(CacheKeys.ContentTypePropertiesCacheKey); //clear the property datatype cache used by razor _propertyTypeCache = new Dictionary, Guid>(); @@ -1176,7 +1153,7 @@ namespace umbraco.cms.businesslogic /// private string GetPropertiesCacheKey() { - return "ContentType_PropertyTypes_Content:" + this.Id; + return CacheKeys.ContentTypePropertiesCacheKey + this.Id; } @@ -1334,9 +1311,7 @@ namespace umbraco.cms.businesslogic [Obsolete("Please use PropertyTypes instead", false)] public class Tab : TabI { - private ContentType _contenttype; - private static object propertyTypesCacheSyncLock = new object(); - public static readonly string CacheKey = "Tab_PropertyTypes_Content:"; + private readonly ContentType _contenttype; /// /// Initializes a new instance of the class. @@ -1430,14 +1405,15 @@ namespace umbraco.cms.businesslogic /// /// The id. /// + [Obsolete("Cache for tabs is automatically refreshed by Umbraco when Property types are modified")] public static void FlushCache(int id, int contentTypeId) { - Cache.ClearCacheItem(generateCacheKey(id, contentTypeId)); + ApplicationContext.Current.ApplicationCache.ClearCacheItem(GenerateCacheKey(id, contentTypeId)); } - private static string generateCacheKey(int tabId, int contentTypeId) + private static string GenerateCacheKey(int tabId, int contentTypeId) { - return String.Format("{0}_{1}_{2}", CacheKey, tabId, contentTypeId); + return String.Format("{0}_{1}_{2}", CacheKeys.PropertyTypeTabCacheKey, tabId, contentTypeId); } /// @@ -1460,7 +1436,7 @@ namespace umbraco.cms.businesslogic { try { - string tempCaption = SqlHelper.ExecuteScalar("Select text from cmsPropertyTypeGroup where id = " + id.ToString()); + var tempCaption = SqlHelper.ExecuteScalar("Select text from cmsPropertyTypeGroup where id = " + id.ToString()); if (!tempCaption.StartsWith("#")) return tempCaption; else @@ -1594,7 +1570,7 @@ namespace umbraco.cms.businesslogic get { return _contenttype.Id; } } - private string _caption; + private readonly string _caption; /// /// The text on the tab @@ -1614,7 +1590,7 @@ namespace umbraco.cms.businesslogic { if (Dictionary.DictionaryItem.hasKey(_caption.Substring(1, _caption.Length - 1))) { - Dictionary.DictionaryItem di = + var di = new Dictionary.DictionaryItem(_caption.Substring(1, _caption.Length - 1)); if (di != null) return di.Value(lang.id); diff --git a/src/umbraco.cms/businesslogic/language/Language.cs b/src/umbraco.cms/businesslogic/language/Language.cs index 938cc14e55..fd1da001ab 100644 --- a/src/umbraco.cms/businesslogic/language/Language.cs +++ b/src/umbraco.cms/businesslogic/language/Language.cs @@ -33,7 +33,7 @@ namespace umbraco.cms.businesslogic.language #region Constants and static members private static object getLanguageSyncLock = new object(); - private static readonly string UmbracoLanguageCacheKey = "UmbracoPropertyTypeCache"; + private static readonly string UmbracoLanguageCacheKey = "UmbracoLanguageCache"; private const int DefaultLanguageId = 1; @@ -149,15 +149,13 @@ namespace umbraco.cms.businesslogic.language /// /// Gets the language by its culture code, if no language is found, null is returned /// - /// The culture code. + /// The culture code. /// public static Language GetByCultureCode(String cultureCode) { if (new CultureInfo(cultureCode) != null) { - return GetAllAsList() - .Where(x => x.CultureAlias == cultureCode) - .SingleOrDefault(); + return GetAllAsList().SingleOrDefault(x => x.CultureAlias == cultureCode); } return null; diff --git a/src/umbraco.cms/businesslogic/propertytype/propertytype.cs b/src/umbraco.cms/businesslogic/propertytype/propertytype.cs index 97563546b9..70ed1771c1 100644 --- a/src/umbraco.cms/businesslogic/propertytype/propertytype.cs +++ b/src/umbraco.cms/businesslogic/propertytype/propertytype.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Threading; +using Umbraco.Core; +using Umbraco.Core.Cache; using Umbraco.Core.Persistence.Caching; using umbraco.BusinessLogic; using umbraco.cms.businesslogic.cache; @@ -22,9 +24,7 @@ namespace umbraco.cms.businesslogic.propertytype public class PropertyType { #region Declarations - - private static readonly object propertyTypeCacheSyncLock = new object(); - private static readonly string UmbracoPropertyTypeCacheKey = "UmbracoPropertyTypeCache"; + private readonly int _contenttypeid; private readonly int _id; private int _DataTypeId; @@ -301,7 +301,7 @@ namespace umbraco.cms.businesslogic.propertytype finally { // Clear cached items - Cache.ClearCacheByKeySearch(UmbracoPropertyTypeCacheKey); + ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch(CacheKeys.PropertyTypeCacheKey); } return pt; @@ -453,10 +453,10 @@ namespace umbraco.cms.businesslogic.propertytype protected virtual void FlushCache() { // clear local cache - Cache.ClearCacheItem(GetCacheKey(Id)); + ApplicationContext.Current.ApplicationCache.ClearCacheItem(GetCacheKey(Id)); // clear cache in contentype - Cache.ClearCacheItem("ContentType_PropertyTypes_Content:" + _contenttypeid); + ApplicationContext.Current.ApplicationCache.ClearCacheItem(CacheKeys.ContentTypePropertiesCacheKey + _contenttypeid); //Ensure that DocumentTypes are reloaded from db by clearing cache - this similar to the Save method on DocumentType. //NOTE Would be nice if we could clear cache by type instead of emptying the entire cache. @@ -466,29 +466,30 @@ namespace umbraco.cms.businesslogic.propertytype public static PropertyType GetPropertyType(int id) { - return Cache.GetCacheItem(GetCacheKey(id), propertyTypeCacheSyncLock, - TimeSpan.FromMinutes(30), - delegate - { - try - { - return new PropertyType(id); - } - catch - { - return null; - } - }); + return ApplicationContext.Current.ApplicationCache.GetCacheItem( + GetCacheKey(id), + TimeSpan.FromMinutes(30), + delegate + { + try + { + return new PropertyType(id); + } + catch + { + return null; + } + }); } private void InvalidateCache() { - Cache.ClearCacheItem(GetCacheKey(Id)); + ApplicationContext.Current.ApplicationCache.ClearCacheItem(GetCacheKey(Id)); } private static string GetCacheKey(int id) { - return UmbracoPropertyTypeCacheKey + id; + return CacheKeys.PropertyTypeCacheKey + id; } #endregion