From ac7cb8febeefdef8f2d0decdf39eded91dcc8d40 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 16 Apr 2014 14:01:26 +1000 Subject: [PATCH] Fixes cache providers to ensure it stores and resolves clones --- .../Caching/InMemoryCacheProvider.cs | 24 ++++++++++++++++--- .../Caching/RuntimeCacheProvider.cs | 14 ++++++++--- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Caching/InMemoryCacheProvider.cs b/src/Umbraco.Core/Persistence/Caching/InMemoryCacheProvider.cs index 5544c74494..7572dcd5c5 100644 --- a/src/Umbraco.Core/Persistence/Caching/InMemoryCacheProvider.cs +++ b/src/Umbraco.Core/Persistence/Caching/InMemoryCacheProvider.cs @@ -37,7 +37,10 @@ namespace Umbraco.Core.Persistence.Caching var containsKey = _cache.ContainsKey(compositeKey); if (containsKey) { - return _cache[compositeKey]; + var result = _cache[compositeKey]; + + //IMPORTANT: we must clone to resolve, see: http://issues.umbraco.org/issue/U4-4259 + return (IEntity)result.DeepClone(); } return null; @@ -56,7 +59,12 @@ namespace Umbraco.Core.Persistence.Caching into key let containsKey = _cache.ContainsKey(key) where containsKey - select _cache[key]).ToList(); + select _cache[key] + into result + //don't return null objects + where result != null + //IMPORTANT: we must clone to resolve, see: http://issues.umbraco.org/issue/U4-4259 + select (IEntity)result.DeepClone()).ToList(); return list; } @@ -67,7 +75,14 @@ namespace Umbraco.Core.Persistence.Caching /// public IEnumerable GetAllByType(Type type) { - var list = _cache.Keys.Where(key => key.Contains(type.Name)).Select(key => _cache[key]).ToList(); + var list = _cache.Keys + .Where(key => key.Contains(type.Name)) + .Select(key => _cache[key]) + //don't return null objects + .Where(result => result != null) + //IMPORTANT: we must clone to resolve, see: http://issues.umbraco.org/issue/U4-4259 + .Select(result => (IEntity)result.DeepClone()) + .ToList(); return list; } @@ -78,6 +93,9 @@ namespace Umbraco.Core.Persistence.Caching /// public void Save(Type type, IEntity entity) { + //IMPORTANT: we must clone to store, see: http://issues.umbraco.org/issue/U4-4259 + entity = (IEntity)entity.DeepClone(); + _cache.AddOrUpdate(GetCompositeId(type, entity.Id), entity, (x, y) => entity); } diff --git a/src/Umbraco.Core/Persistence/Caching/RuntimeCacheProvider.cs b/src/Umbraco.Core/Persistence/Caching/RuntimeCacheProvider.cs index ff6db47860..c2ca53a240 100644 --- a/src/Umbraco.Core/Persistence/Caching/RuntimeCacheProvider.cs +++ b/src/Umbraco.Core/Persistence/Caching/RuntimeCacheProvider.cs @@ -67,8 +67,11 @@ namespace Umbraco.Core.Persistence.Caching { //ensure the key doesn't exist anymore in the tracker _keyTracker.Remove(key); + return null; } - return result; + + //IMPORTANT: we must clone to resolve, see: http://issues.umbraco.org/issue/U4-4259 + return (IEntity)result.DeepClone(); } public IEnumerable GetByIds(Type type, List ids) @@ -88,7 +91,8 @@ namespace Umbraco.Core.Persistence.Caching } else { - collection.Add(result); + //IMPORTANT: we must clone to resolve, see: http://issues.umbraco.org/issue/U4-4259 + collection.Add((IEntity)result.DeepClone()); } } return collection; @@ -113,7 +117,8 @@ namespace Umbraco.Core.Persistence.Caching } else { - collection.Add(result); + //IMPORTANT: we must clone to resolve, see: http://issues.umbraco.org/issue/U4-4259 + collection.Add((IEntity)result.DeepClone()); } } } @@ -122,6 +127,9 @@ namespace Umbraco.Core.Persistence.Caching public void Save(Type type, IEntity entity) { + //IMPORTANT: we must clone to store, see: http://issues.umbraco.org/issue/U4-4259 + entity = (IEntity)entity.DeepClone(); + var key = GetCompositeId(type, entity.Id); _keyTracker.TryAdd(key);