diff --git a/src/Umbraco.Core/Cache/DefaultRepositoryCachePolicy.cs b/src/Umbraco.Core/Cache/DefaultRepositoryCachePolicy.cs
index 1f51fc3ccc..656d532d8a 100644
--- a/src/Umbraco.Core/Cache/DefaultRepositoryCachePolicy.cs
+++ b/src/Umbraco.Core/Cache/DefaultRepositoryCachePolicy.cs
@@ -1,23 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using Umbraco.Core.Logging;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Cache
{
///
- /// The default cache policy for retrieving a single entity
+ /// Represents the default cache policy.
///
- ///
- ///
+ /// The type of the entity.
+ /// The type of the identifier.
///
- /// This cache policy uses sliding expiration and caches instances for 5 minutes. However if allow zero count is true, then we use the
- /// default policy with no expiry.
+ /// The default cache policy caches entities with a 5 minutes sliding expiration.
+ /// Each entity is cached individually.
+ /// If options.GetAllCacheAllowZeroCount then a 'zero-count' array is cached when GetAll finds nothing.
+ /// If options.GetAllCacheValidateCount then we check against the db when getting many entities.
///
internal class DefaultRepositoryCachePolicy : RepositoryCachePolicyBase
where TEntity : class, IAggregateRoot
{
+ private static readonly TEntity[] EmptyEntities = new TEntity[0]; // const
private readonly RepositoryCachePolicyOptions _options;
public DefaultRepositoryCachePolicy(IRuntimeCacheProvider cache, RepositoryCachePolicyOptions options)
@@ -27,242 +29,216 @@ namespace Umbraco.Core.Cache
_options = options;
}
- protected string GetCacheIdKey(object id)
+ protected string GetEntityCacheKey(object id)
{
if (id == null) throw new ArgumentNullException("id");
-
- return string.Format("{0}{1}", GetCacheTypeKey(), id);
+ return GetEntityTypeCacheKey() + id;
}
- protected string GetCacheTypeKey()
+ protected string GetEntityTypeCacheKey()
{
return string.Format("uRepo_{0}_", typeof(TEntity).Name);
}
- public override void CreateOrUpdate(TEntity entity, Action persistMethod)
+ protected virtual void InsertEntity(string cacheKey, TEntity entity)
+ {
+ Cache.InsertCacheItem(cacheKey, () => entity, TimeSpan.FromMinutes(5), true);
+ }
+
+ protected virtual void InsertEntities(TId[] ids, TEntity[] entities)
+ {
+ if (ids.Length == 0 && entities.Length == 0 && _options.GetAllCacheAllowZeroCount)
+ {
+ // getting all of them, and finding nothing.
+ // if we can cache a zero count, cache an empty array,
+ // for as long as the cache is not cleared (no expiration)
+ Cache.InsertCacheItem(GetEntityTypeCacheKey(), () => EmptyEntities);
+ }
+ else
+ {
+ // individually cache each item
+ foreach (var entity in entities)
+ {
+ var capture = entity;
+ Cache.InsertCacheItem(GetEntityCacheKey(entity.Id), () => capture, TimeSpan.FromMinutes(5), true);
+ }
+ }
+ }
+
+ ///
+ public override void Create(TEntity entity, Action persistNew)
{
if (entity == null) throw new ArgumentNullException("entity");
- if (persistMethod == null) throw new ArgumentNullException("persistMethod");
try
{
- persistMethod(entity);
+ persistNew(entity);
- //set the disposal action
- SetCacheAction(() =>
+ // just to be safe, we cannot cache an item without an identity
+ if (entity.HasIdentity)
{
- //just to be safe, we cannot cache an item without an identity
- if (entity.HasIdentity)
- {
- Cache.InsertCacheItem(GetCacheIdKey(entity.Id), () => entity,
- timeout: TimeSpan.FromMinutes(5),
- isSliding: true);
- }
-
- //If there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
- Cache.ClearCacheItem(GetCacheTypeKey());
- });
-
+ Cache.InsertCacheItem(GetEntityCacheKey(entity.Id), () => entity, TimeSpan.FromMinutes(5), true);
+ }
+
+ // if there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
+ Cache.ClearCacheItem(GetEntityTypeCacheKey());
}
catch
{
- //set the disposal action
- SetCacheAction(() =>
- {
- //if an exception is thrown we need to remove the entry from cache, this is ONLY a work around because of the way
- // that we cache entities: http://issues.umbraco.org/issue/U4-4259
- Cache.ClearCacheItem(GetCacheIdKey(entity.Id));
+ // if an exception is thrown we need to remove the entry from cache,
+ // this is ONLY a work around because of the way
+ // that we cache entities: http://issues.umbraco.org/issue/U4-4259
+ Cache.ClearCacheItem(GetEntityCacheKey(entity.Id));
+
+ // if there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
+ Cache.ClearCacheItem(GetEntityTypeCacheKey());
- //If there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
- Cache.ClearCacheItem(GetCacheTypeKey());
- });
-
throw;
}
}
- public override void Remove(TEntity entity, Action persistMethod)
+ ///
+ public override void Update(TEntity entity, Action persistUpdated)
{
if (entity == null) throw new ArgumentNullException("entity");
- if (persistMethod == null) throw new ArgumentNullException("persistMethod");
try
{
- persistMethod(entity);
- }
- finally
- {
- //set the disposal action
- var cacheKey = GetCacheIdKey(entity.Id);
- SetCacheAction(() =>
+ persistUpdated(entity);
+
+ // just to be safe, we cannot cache an item without an identity
+ if (entity.HasIdentity)
{
- Cache.ClearCacheItem(cacheKey);
- //If there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
- Cache.ClearCacheItem(GetCacheTypeKey());
- });
+ Cache.InsertCacheItem(GetEntityCacheKey(entity.Id), () => entity, TimeSpan.FromMinutes(5), true);
+ }
+
+ // if there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
+ Cache.ClearCacheItem(GetEntityTypeCacheKey());
+ }
+ catch
+ {
+ // if an exception is thrown we need to remove the entry from cache,
+ // this is ONLY a work around because of the way
+ // that we cache entities: http://issues.umbraco.org/issue/U4-4259
+ Cache.ClearCacheItem(GetEntityCacheKey(entity.Id));
+
+ // if there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
+ Cache.ClearCacheItem(GetEntityTypeCacheKey());
+
+ throw;
}
}
- public override TEntity Get(TId id, Func getFromRepo)
+ ///
+ public override void Delete(TEntity entity, Action persistDeleted)
{
- if (getFromRepo == null) throw new ArgumentNullException("getFromRepo");
+ if (entity == null) throw new ArgumentNullException("entity");
- var cacheKey = GetCacheIdKey(id);
+ try
+ {
+ persistDeleted(entity);
+ }
+ finally
+ {
+ // whatever happens, clear the cache
+ var cacheKey = GetEntityCacheKey(entity.Id);
+ Cache.ClearCacheItem(cacheKey);
+ // if there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
+ Cache.ClearCacheItem(GetEntityTypeCacheKey());
+ }
+ }
+
+ ///
+ public override TEntity Get(TId id, Func performGet, Func> performGetAll)
+ {
+ var cacheKey = GetEntityCacheKey(id);
var fromCache = Cache.GetCacheItem(cacheKey);
+
+ // if found in cache then return else fetch and cache
if (fromCache != null)
return fromCache;
-
- var entity = getFromRepo(id);
+ var entity = performGet(id);
- //set the disposal action
- SetCacheAction(cacheKey, entity);
+ if (entity != null && entity.HasIdentity)
+ InsertEntity(cacheKey, entity);
return entity;
}
- public override TEntity Get(TId id)
+ ///
+ public override TEntity GetCached(TId id)
{
- var cacheKey = GetCacheIdKey(id);
+ var cacheKey = GetEntityCacheKey(id);
return Cache.GetCacheItem(cacheKey);
}
- public override bool Exists(TId id, Func getFromRepo)
+ ///
+ public override bool Exists(TId id, Func performExists, Func> performGetAll)
{
- if (getFromRepo == null) throw new ArgumentNullException("getFromRepo");
-
- var cacheKey = GetCacheIdKey(id);
+ // if found in cache the return else check
+ var cacheKey = GetEntityCacheKey(id);
var fromCache = Cache.GetCacheItem(cacheKey);
- return fromCache != null || getFromRepo(id);
+ return fromCache != null || performExists(id);
}
- public override TEntity[] GetAll(TId[] ids, Func> getFromRepo)
+ ///
+ public override TEntity[] GetAll(TId[] ids, Func> performGetAll)
{
- if (getFromRepo == null) throw new ArgumentNullException("getFromRepo");
-
- if (ids.Any())
+ if (ids.Length > 0)
{
- var entities = ids.Select(Get).ToArray();
- if (ids.Length.Equals(entities.Length) && entities.Any(x => x == null) == false)
- return entities;
+ // try to get each entity from the cache
+ // if we can find all of them, return
+ var entities = ids.Select(GetCached).WhereNotNull().ToArray();
+ if (ids.Length.Equals(entities.Length))
+ return entities; // no need for null checks, we are not caching nulls
}
else
{
- var allEntities = GetAllFromCache();
- if (allEntities.Any())
+ // get everything we have
+ var entities = Cache.GetCacheItemsByKeySearch(GetEntityTypeCacheKey())
+ .ToArray(); // no need for null checks, we are not caching nulls
+
+ if (entities.Length > 0)
{
+ // if some of them were in the cache...
if (_options.GetAllCacheValidateCount)
{
- //Get count of all entities of current type (TEntity) to ensure cached result is correct
+ // need to validate the count, get the actual count and return if ok
var totalCount = _options.PerformCount();
- if (allEntities.Length == totalCount)
- return allEntities;
+ if (entities.Length == totalCount)
+ return entities;
}
else
{
- return allEntities;
+ // no need to validate, just return what we have and assume it's all there is
+ return entities;
}
}
else if (_options.GetAllCacheAllowZeroCount)
{
- //if the repository allows caching a zero count, then check the zero count cache
- if (HasZeroCountCache())
- {
- //there is a zero count cache so return an empty list
- return new TEntity[] {};
- }
+ // if none of them were in the cache
+ // and we allow zero count - check for the special (empty) entry
+ var empty = Cache.GetCacheItem(GetEntityTypeCacheKey());
+ if (empty != null) return empty;
}
}
- //we need to do the lookup from the repo
- var entityCollection = getFromRepo(ids)
- //ensure we don't include any null refs in the returned collection!
- .WhereNotNull()
+ // cache failed, get from repo and cache
+ var repoEntities = performGetAll(ids)
+ .WhereNotNull() // exclude nulls!
+ .Where(x => x.HasIdentity) // be safe, though would be weird...
.ToArray();
- //set the disposal action
- SetCacheAction(ids, entityCollection);
+ // note: if empty & allow zero count, will cache a special (empty) entry
+ InsertEntities(ids, repoEntities);
- return entityCollection;
+ return repoEntities;
}
- ///
- /// Looks up the zero count cache, must return null if it doesn't exist
- ///
- ///
- protected bool HasZeroCountCache()
+ ///
+ public override void ClearAll()
{
- var zeroCount = Cache.GetCacheItem(GetCacheTypeKey());
- return (zeroCount != null && zeroCount.Any() == false);
+ Cache.ClearCacheByKeySearch(GetEntityTypeCacheKey());
}
-
- ///
- /// Performs the lookup for all entities of this type from the cache
- ///
- ///
- protected TEntity[] GetAllFromCache()
- {
- var allEntities = Cache.GetCacheItemsByKeySearch(GetCacheTypeKey())
- .WhereNotNull()
- .ToArray();
- return allEntities.Any() ? allEntities : new TEntity[] {};
- }
-
- ///
- /// Sets the action to execute on disposal for a single entity
- ///
- ///
- ///
- protected virtual void SetCacheAction(string cacheKey, TEntity entity)
- {
- if (entity == null) return;
-
- SetCacheAction(() =>
- {
- //just to be safe, we cannot cache an item without an identity
- if (entity.HasIdentity)
- {
- Cache.InsertCacheItem(cacheKey, () => entity,
- timeout: TimeSpan.FromMinutes(5),
- isSliding: true);
- }
- });
- }
-
- ///
- /// Sets the action to execute on disposal for an entity collection
- ///
- ///
- ///
- protected virtual void SetCacheAction(TId[] ids, TEntity[] entityCollection)
- {
- SetCacheAction(() =>
- {
- //This option cannot execute if we are looking up specific Ids
- if (ids.Any() == false && entityCollection.Length == 0 && _options.GetAllCacheAllowZeroCount)
- {
- //there was nothing returned but we want to cache a zero count result so add an TEntity[] to the cache
- // to signify that there is a zero count cache
- //NOTE: Don't set expiry/sliding for a zero count
- Cache.InsertCacheItem(GetCacheTypeKey(), () => new TEntity[] {});
- }
- else
- {
- //This is the default behavior, we'll individually cache each item so that if/when these items are resolved
- // by id, they are returned from the already existing cache.
- foreach (var entity in entityCollection.WhereNotNull())
- {
- var localCopy = entity;
- //just to be safe, we cannot cache an item without an identity
- if (localCopy.HasIdentity)
- {
- Cache.InsertCacheItem(GetCacheIdKey(entity.Id), () => localCopy,
- timeout: TimeSpan.FromMinutes(5),
- isSliding: true);
- }
- }
- }
- });
- }
-
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Cache/DefaultRepositoryCachePolicyFactory.cs b/src/Umbraco.Core/Cache/DefaultRepositoryCachePolicyFactory.cs
deleted file mode 100644
index 5c02e41a48..0000000000
--- a/src/Umbraco.Core/Cache/DefaultRepositoryCachePolicyFactory.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using Umbraco.Core.Models.EntityBase;
-
-namespace Umbraco.Core.Cache
-{
- ///
- /// Creates cache policies
- ///
- ///
- ///
- internal class DefaultRepositoryCachePolicyFactory : IRepositoryCachePolicyFactory
- where TEntity : class, IAggregateRoot
- {
- private readonly IRuntimeCacheProvider _runtimeCache;
- private readonly RepositoryCachePolicyOptions _options;
-
- public DefaultRepositoryCachePolicyFactory(IRuntimeCacheProvider runtimeCache, RepositoryCachePolicyOptions options)
- {
- _runtimeCache = runtimeCache;
- _options = options;
- }
-
- public virtual IRepositoryCachePolicy CreatePolicy()
- {
- return new DefaultRepositoryCachePolicy(_runtimeCache, _options);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Cache/FullDataSetRepositoryCachePolicy.cs b/src/Umbraco.Core/Cache/FullDataSetRepositoryCachePolicy.cs
index 9b37d1861f..95ad7e2bf0 100644
--- a/src/Umbraco.Core/Cache/FullDataSetRepositoryCachePolicy.cs
+++ b/src/Umbraco.Core/Cache/FullDataSetRepositoryCachePolicy.cs
@@ -7,223 +7,168 @@ using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Cache
{
///
- /// A caching policy that caches an entire dataset as a single collection
+ /// Represents a caching policy that caches the entire entities set as a single collection.
///
- ///
- ///
+ /// The type of the entity.
+ /// The type of the identifier.
+ ///
+ /// Caches the entire set of entities as a single collection.
+ /// Used by Content-, Media- and MemberTypeRepository, DataTypeRepository, DomainRepository,
+ /// LanguageRepository, PublicAccessRepository, TemplateRepository... things that make sense to
+ /// keep as a whole in memory.
+ ///
internal class FullDataSetRepositoryCachePolicy : RepositoryCachePolicyBase
where TEntity : class, IAggregateRoot
{
- private readonly Func _getEntityId;
- private readonly Func> _getAllFromRepo;
+ private readonly Func _entityGetId;
private readonly bool _expires;
- public FullDataSetRepositoryCachePolicy(IRuntimeCacheProvider cache, Func getEntityId, Func> getAllFromRepo, bool expires)
+ public FullDataSetRepositoryCachePolicy(IRuntimeCacheProvider cache, Func entityGetId, bool expires)
: base(cache)
{
- _getEntityId = getEntityId;
- _getAllFromRepo = getAllFromRepo;
+ _entityGetId = entityGetId;
_expires = expires;
}
- private bool? _hasZeroCountCache;
+ protected static readonly TId[] EmptyIds = new TId[0]; // const
-
- protected string GetCacheTypeKey()
+ protected string GetEntityTypeCacheKey()
{
return string.Format("uRepo_{0}_", typeof(TEntity).Name);
}
- public override void CreateOrUpdate(TEntity entity, Action persistMethod)
+ protected void InsertEntities(TEntity[] entities)
{
- if (entity == null) throw new ArgumentNullException("entity");
- if (persistMethod == null) throw new ArgumentNullException("persistMethod");
+ // cache is expected to be a deep-cloning cache ie it deep-clones whatever is
+ // IDeepCloneable when it goes in, and out. it also resets dirty properties,
+ // making sure that no 'dirty' entity is cached.
+ //
+ // this policy is caching the entire list of entities. to ensure that entities
+ // are properly deep-clones when cached, it uses a DeepCloneableList. however,
+ // we don't want to deep-clone *each* entity in the list when fetching it from
+ // cache as that would not be efficient for Get(id). so the DeepCloneableList is
+ // set to ListCloneBehavior.CloneOnce ie it will clone *once* when inserting,
+ // and then will *not* clone when retrieving.
- try
+ if (_expires)
{
- persistMethod(entity);
-
- //set the disposal action
- SetCacheAction(() =>
- {
- //Clear all
- Cache.ClearCacheItem(GetCacheTypeKey());
- });
+ Cache.InsertCacheItem(GetEntityTypeCacheKey(), () => new DeepCloneableList(entities), TimeSpan.FromMinutes(5), true);
}
- catch
+ else
{
- //set the disposal action
- SetCacheAction(() =>
- {
- //Clear all
- Cache.ClearCacheItem(GetCacheTypeKey());
- });
- throw;
+ Cache.InsertCacheItem(GetEntityTypeCacheKey(), () => new DeepCloneableList(entities));
}
}
- public override void Remove(TEntity entity, Action persistMethod)
+ ///
+ public override void Create(TEntity entity, Action persistNew)
{
if (entity == null) throw new ArgumentNullException("entity");
- if (persistMethod == null) throw new ArgumentNullException("persistMethod");
try
{
- persistMethod(entity);
+ persistNew(entity);
}
finally
{
- //set the disposal action
- SetCacheAction(() =>
- {
- //Clear all
- Cache.ClearCacheItem(GetCacheTypeKey());
- });
+ ClearAll();
}
}
- public override TEntity Get(TId id, Func getFromRepo)
+ ///
+ public override void Update(TEntity entity, Action persistUpdated)
{
- //Force get all with cache
- var found = GetAll(new TId[] { }, ids => _getAllFromRepo().WhereNotNull());
+ if (entity == null) throw new ArgumentNullException("entity");
- //we don't have anything in cache (this should never happen), just return from the repo
- if (found == null) return getFromRepo(id);
- var entity = found.FirstOrDefault(x => _getEntityId(x).Equals(id));
- if (entity == null) return null;
-
- //We must ensure to deep clone each one out manually since the deep clone list only clones one way
- return (TEntity)entity.DeepClone();
- }
-
- public override TEntity Get(TId id)
- {
- //Force get all with cache
- var found = GetAll(new TId[] { }, ids => _getAllFromRepo().WhereNotNull());
-
- //we don't have anything in cache (this should never happen), just return null
- if (found == null) return null;
- var entity = found.FirstOrDefault(x => _getEntityId(x).Equals(id));
- if (entity == null) return null;
-
- //We must ensure to deep clone each one out manually since the deep clone list only clones one way
- return (TEntity)entity.DeepClone();
- }
-
- public override bool Exists(TId id, Func getFromRepo)
- {
- //Force get all with cache
- var found = GetAll(new TId[] { }, ids => _getAllFromRepo().WhereNotNull());
-
- //we don't have anything in cache (this should never happen), just return from the repo
- return found == null
- ? getFromRepo(id)
- : found.Any(x => _getEntityId(x).Equals(id));
- }
-
- public override TEntity[] GetAll(TId[] ids, Func> getFromRepo)
- {
- //process getting all including setting the cache callback
- var result = PerformGetAll(getFromRepo);
-
- //now that the base result has been calculated, they will all be cached.
- // Now we can just filter by ids if they have been supplied
-
- return (ids.Any()
- ? result.Where(x => ids.Contains(_getEntityId(x))).ToArray()
- : result)
- //We must ensure to deep clone each one out manually since the deep clone list only clones one way
- .Select(x => (TEntity)x.DeepClone())
- .ToArray();
- }
-
- private TEntity[] PerformGetAll(Func> getFromRepo)
- {
- var allEntities = GetAllFromCache();
- if (allEntities.Any())
+ try
{
- return allEntities;
+ persistUpdated(entity);
}
-
- //check the zero count cache
- if (HasZeroCountCache())
+ finally
{
- //there is a zero count cache so return an empty list
- return new TEntity[] { };
+ ClearAll();
}
-
- //we need to do the lookup from the repo
- var entityCollection = getFromRepo(new TId[] { })
- //ensure we don't include any null refs in the returned collection!
- .WhereNotNull()
- .ToArray();
-
- //set the disposal action
- SetCacheAction(entityCollection);
-
- return entityCollection;
}
- ///
- /// For this type of caching policy, we don't cache individual items
- ///
- ///
- ///
- protected void SetCacheAction(string cacheKey, TEntity entity)
+ ///
+ public override void Delete(TEntity entity, Action persistDeleted)
{
- //No-op
- }
+ if (entity == null) throw new ArgumentNullException("entity");
- ///
- /// Sets the action to execute on disposal for an entity collection
- ///
- ///
- protected void SetCacheAction(TEntity[] entityCollection)
- {
- //set the disposal action
- SetCacheAction(() =>
+ try
{
- //We want to cache the result as a single collection
-
- if (_expires)
- {
- Cache.InsertCacheItem(GetCacheTypeKey(), () => new DeepCloneableList(entityCollection),
- timeout: TimeSpan.FromMinutes(5),
- isSliding: true);
- }
- else
- {
- Cache.InsertCacheItem(GetCacheTypeKey(), () => new DeepCloneableList(entityCollection));
- }
- });
+ persistDeleted(entity);
+ }
+ finally
+ {
+ ClearAll();
+ }
}
- ///
- /// Looks up the zero count cache, must return null if it doesn't exist
- ///
- ///
- protected bool HasZeroCountCache()
+ ///
+ public override TEntity Get(TId id, Func performGet, Func> performGetAll)
{
- if (_hasZeroCountCache.HasValue)
- return _hasZeroCountCache.Value;
+ // get all from the cache, then look for the entity
+ var all = GetAllCached(performGetAll);
+ var entity = all.FirstOrDefault(x => _entityGetId(x).Equals(id));
- _hasZeroCountCache = Cache.GetCacheItem>(GetCacheTypeKey()) != null;
- return _hasZeroCountCache.Value;
+ // see note in InsertEntities - what we get here is the original
+ // cached entity, not a clone, so we need to manually ensure it is deep-cloned.
+ return entity == null ? null : (TEntity) entity.DeepClone();
}
- ///
- /// This policy will cache the full data set as a single collection
- ///
- ///
- protected TEntity[] GetAllFromCache()
+ ///
+ public override TEntity GetCached(TId id)
{
- var found = Cache.GetCacheItem>(GetCacheTypeKey());
+ // get all from the cache -- and only the cache, then look for the entity
+ var all = Cache.GetCacheItem>(GetEntityTypeCacheKey());
+ var entity = all == null ? null : all.FirstOrDefault(x => _entityGetId(x).Equals(id));
- //This method will get called before checking for zero count cache, so we'll just set the flag here
- _hasZeroCountCache = found != null;
-
- return found == null ? new TEntity[] { } : found.WhereNotNull().ToArray();
+ // see note in InsertEntities - what we get here is the original
+ // cached entity, not a clone, so we need to manually ensure it is deep-cloned.
+ return entity == null ? null : (TEntity)entity.DeepClone();
}
+ ///
+ public override bool Exists(TId id, Func performExits, Func> performGetAll)
+ {
+ // get all as one set, then look for the entity
+ var all = GetAllCached(performGetAll);
+ return all.Any(x => _entityGetId(x).Equals(id));
+ }
+
+ ///
+ public override TEntity[] GetAll(TId[] ids, Func> performGetAll)
+ {
+ // get all as one set, from cache if possible, else repo
+ var all = GetAllCached(performGetAll);
+
+ // if ids have been specified, filter
+ if (ids.Length > 0) all = all.Where(x => ids.Contains(_entityGetId(x)));
+
+ // and return
+ // see note in SetCacheActionToInsertEntities - what we get here is the original
+ // cached entities, not clones, so we need to manually ensure they are deep-cloned.
+ return all.Select(x => (TEntity) x.DeepClone()).ToArray();
+ }
+
+ // does NOT clone anything, so be nice with the returned values
+ private IEnumerable GetAllCached(Func> performGetAll)
+ {
+ // try the cache first
+ var all = Cache.GetCacheItem>(GetEntityTypeCacheKey());
+ if (all != null) return all.ToArray();
+
+ // else get from repo and cache
+ var entities = performGetAll(EmptyIds).WhereNotNull().ToArray();
+ InsertEntities(entities); // may be an empty array...
+ return entities;
+ }
+
+ ///
+ public override void ClearAll()
+ {
+ Cache.ClearCacheItem(GetEntityTypeCacheKey());
+ }
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Cache/FullDataSetRepositoryCachePolicyFactory.cs b/src/Umbraco.Core/Cache/FullDataSetRepositoryCachePolicyFactory.cs
deleted file mode 100644
index e4addcf355..0000000000
--- a/src/Umbraco.Core/Cache/FullDataSetRepositoryCachePolicyFactory.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using System;
-using System.Collections.Generic;
-using Umbraco.Core.Models.EntityBase;
-
-namespace Umbraco.Core.Cache
-{
- ///
- /// Creates cache policies
- ///
- ///
- ///
- internal class FullDataSetRepositoryCachePolicyFactory : IRepositoryCachePolicyFactory
- where TEntity : class, IAggregateRoot
- {
- private readonly IRuntimeCacheProvider _runtimeCache;
- private readonly Func _getEntityId;
- private readonly Func> _getAllFromRepo;
- private readonly bool _expires;
-
- public FullDataSetRepositoryCachePolicyFactory(IRuntimeCacheProvider runtimeCache, Func getEntityId, Func> getAllFromRepo, bool expires)
- {
- _runtimeCache = runtimeCache;
- _getEntityId = getEntityId;
- _getAllFromRepo = getAllFromRepo;
- _expires = expires;
- }
-
- public virtual IRepositoryCachePolicy CreatePolicy()
- {
- return new FullDataSetRepositoryCachePolicy(_runtimeCache, _getEntityId, _getAllFromRepo, _expires);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Cache/IRepositoryCachePolicy.cs b/src/Umbraco.Core/Cache/IRepositoryCachePolicy.cs
index 215487c3be..11a3cf6bb9 100644
--- a/src/Umbraco.Core/Cache/IRepositoryCachePolicy.cs
+++ b/src/Umbraco.Core/Cache/IRepositoryCachePolicy.cs
@@ -4,15 +4,83 @@ using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Cache
{
- internal interface IRepositoryCachePolicy : IDisposable
+ internal interface IRepositoryCachePolicy
where TEntity : class, IAggregateRoot
{
- TEntity Get(TId id, Func getFromRepo);
- TEntity Get(TId id);
- bool Exists(TId id, Func getFromRepo);
-
- void CreateOrUpdate(TEntity entity, Action persistMethod);
- void Remove(TEntity entity, Action persistMethod);
- TEntity[] GetAll(TId[] ids, Func> getFromRepo);
+ // note:
+ // at the moment each repository instance creates its corresponding cache policy instance
+ // we could reduce allocations by using static cache policy instances but then we would need
+ // to modify all methods here to pass the repository and cache eg:
+ //
+ // TEntity Get(TRepository repository, IRuntimeCacheProvider cache, TId id);
+ //
+ // it is not *that* complicated but then RepositoryBase needs to have a TRepository generic
+ // type parameter and it all becomes convoluted - keeping it simple for the time being.
+
+ ///
+ /// Gets an entity from the cache, else from the repository.
+ ///
+ /// The identifier.
+ /// The repository PerformGet method.
+ /// The repository PerformGetAll method.
+ /// The entity with the specified identifier, if it exits, else null.
+ /// First considers the cache then the repository.
+ TEntity Get(TId id, Func performGet, Func> performGetAll);
+
+ ///
+ /// Gets an entity from the cache.
+ ///
+ /// The identifier.
+ /// The entity with the specified identifier, if it is in the cache already, else null.
+ /// Does not consider the repository at all.
+ TEntity GetCached(TId id);
+
+ ///
+ /// Gets a value indicating whether an entity with a specified identifier exists.
+ ///
+ /// The identifier.
+ /// The repository PerformExists method.
+ /// The repository PerformGetAll method.
+ /// A value indicating whether an entity with the specified identifier exists.
+ /// First considers the cache then the repository.
+ bool Exists(TId id, Func performExists, Func> performGetAll);
+
+ ///
+ /// Creates an entity.
+ ///
+ /// The entity.
+ /// The repository PersistNewItem method.
+ /// Creates the entity in the repository, and updates the cache accordingly.
+ void Create(TEntity entity, Action persistNew);
+
+ ///
+ /// Updates an entity.
+ ///
+ /// The entity.
+ /// The reopsitory PersistUpdatedItem method.
+ /// Updates the entity in the repository, and updates the cache accordingly.
+ void Update(TEntity entity, Action persistUpdated);
+
+ ///
+ /// Removes an entity.
+ ///
+ /// The entity.
+ /// The repository PersistDeletedItem method.
+ /// Removes the entity from the repository and clears the cache.
+ void Delete(TEntity entity, Action persistDeleted);
+
+ ///
+ /// Gets entities.
+ ///
+ /// The identifiers.
+ /// The repository PerformGetAll method.
+ /// If is empty, all entities, else the entities with the specified identifiers.
+ /// Get all the entities. Either from the cache or the repository depending on the implementation.
+ TEntity[] GetAll(TId[] ids, Func> performGetAll);
+
+ ///
+ /// Clears the entire cache.
+ ///
+ void ClearAll();
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Cache/IRepositoryCachePolicyFactory.cs b/src/Umbraco.Core/Cache/IRepositoryCachePolicyFactory.cs
deleted file mode 100644
index 2d69704b63..0000000000
--- a/src/Umbraco.Core/Cache/IRepositoryCachePolicyFactory.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using Umbraco.Core.Models.EntityBase;
-
-namespace Umbraco.Core.Cache
-{
- internal interface IRepositoryCachePolicyFactory where TEntity : class, IAggregateRoot
- {
- IRepositoryCachePolicy CreatePolicy();
- }
-}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Cache/OnlySingleItemsRepositoryCachePolicyFactory.cs b/src/Umbraco.Core/Cache/OnlySingleItemsRepositoryCachePolicyFactory.cs
deleted file mode 100644
index b24838bc3b..0000000000
--- a/src/Umbraco.Core/Cache/OnlySingleItemsRepositoryCachePolicyFactory.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using Umbraco.Core.Models.EntityBase;
-
-namespace Umbraco.Core.Cache
-{
- ///
- /// Creates cache policies
- ///
- ///
- ///
- internal class OnlySingleItemsRepositoryCachePolicyFactory : IRepositoryCachePolicyFactory
- where TEntity : class, IAggregateRoot
- {
- private readonly IRuntimeCacheProvider _runtimeCache;
- private readonly RepositoryCachePolicyOptions _options;
-
- public OnlySingleItemsRepositoryCachePolicyFactory(IRuntimeCacheProvider runtimeCache, RepositoryCachePolicyOptions options)
- {
- _runtimeCache = runtimeCache;
- _options = options;
- }
-
- public virtual IRepositoryCachePolicy CreatePolicy()
- {
- return new SingleItemsOnlyRepositoryCachePolicy(_runtimeCache, _options);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Cache/RepositoryCachePolicyBase.cs b/src/Umbraco.Core/Cache/RepositoryCachePolicyBase.cs
index b939cd14e6..ce366e3d0b 100644
--- a/src/Umbraco.Core/Cache/RepositoryCachePolicyBase.cs
+++ b/src/Umbraco.Core/Cache/RepositoryCachePolicyBase.cs
@@ -4,45 +4,45 @@ using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Cache
{
- internal abstract class RepositoryCachePolicyBase : DisposableObject, IRepositoryCachePolicy
+ ///
+ /// A base class for repository cache policies.
+ ///
+ /// The type of the entity.
+ /// The type of the identifier.
+ internal abstract class RepositoryCachePolicyBase : IRepositoryCachePolicy
where TEntity : class, IAggregateRoot
{
- private Action _action;
-
protected RepositoryCachePolicyBase(IRuntimeCacheProvider cache)
{
- if (cache == null) throw new ArgumentNullException("cache");
-
+ if (cache == null) throw new ArgumentNullException("cache");
Cache = cache;
}
protected IRuntimeCacheProvider Cache { get; private set; }
- ///
- /// The disposal performs the caching
- ///
- protected override void DisposeResources()
- {
- if (_action != null)
- {
- _action();
- }
- }
+ ///
+ public abstract TEntity Get(TId id, Func performGet, Func> performGetAll);
- ///
- /// Sets the action to execute on disposal
- ///
- ///
- protected void SetCacheAction(Action action)
- {
- _action = action;
- }
+ ///
+ public abstract TEntity GetCached(TId id);
+
+ ///
+ public abstract bool Exists(TId id, Func performExists, Func> performGetAll);
+
+ ///
+ public abstract void Create(TEntity entity, Action persistNew);
+
+ ///
+ public abstract void Update(TEntity entity, Action persistUpdated);
+
+ ///
+ public abstract void Delete(TEntity entity, Action persistDeleted);
+
+ ///
+ public abstract TEntity[] GetAll(TId[] ids, Func> performGetAll);
+
+ ///
+ public abstract void ClearAll();
- public abstract TEntity Get(TId id, Func getFromRepo);
- public abstract TEntity Get(TId id);
- public abstract bool Exists(TId id, Func getFromRepo);
- public abstract void CreateOrUpdate(TEntity entity, Action persistMethod);
- public abstract void Remove(TEntity entity, Action persistMethod);
- public abstract TEntity[] GetAll(TId[] ids, Func> getFromRepo);
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Cache/RepositoryCachePolicyOptions.cs b/src/Umbraco.Core/Cache/RepositoryCachePolicyOptions.cs
index e8c6ac02b0..14cef76db6 100644
--- a/src/Umbraco.Core/Cache/RepositoryCachePolicyOptions.cs
+++ b/src/Umbraco.Core/Cache/RepositoryCachePolicyOptions.cs
@@ -2,6 +2,9 @@ using System;
namespace Umbraco.Core.Cache
{
+ ///
+ /// Specifies how a repository cache policy should cache entities.
+ ///
internal class RepositoryCachePolicyOptions
{
///
diff --git a/src/Umbraco.Core/Cache/SingleItemsOnlyRepositoryCachePolicy.cs b/src/Umbraco.Core/Cache/SingleItemsOnlyRepositoryCachePolicy.cs
index 28ac4ee2d1..7ba7d445fe 100644
--- a/src/Umbraco.Core/Cache/SingleItemsOnlyRepositoryCachePolicy.cs
+++ b/src/Umbraco.Core/Cache/SingleItemsOnlyRepositoryCachePolicy.cs
@@ -1,24 +1,27 @@
-using System.Linq;
-using Umbraco.Core.Collections;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Cache
{
///
- /// A caching policy that ignores all caches for GetAll - it will only cache calls for individual items
+ /// Represents a special policy that does not cache the result of GetAll.
///
- ///
- ///
+ /// The type of the entity.
+ /// The type of the identifier.
+ ///
+ /// Overrides the default repository cache policy and does not writes the result of GetAll
+ /// to cache, but only the result of individual Gets. It does read the cache for GetAll, though.
+ /// Used by DictionaryRepository.
+ ///
internal class SingleItemsOnlyRepositoryCachePolicy : DefaultRepositoryCachePolicy
where TEntity : class, IAggregateRoot
{
- public SingleItemsOnlyRepositoryCachePolicy(IRuntimeCacheProvider cache, RepositoryCachePolicyOptions options) : base(cache, options)
+ public SingleItemsOnlyRepositoryCachePolicy(IRuntimeCacheProvider cache, RepositoryCachePolicyOptions options)
+ : base(cache, options)
+ { }
+
+ protected override void InsertEntities(TId[] ids, TEntity[] entities)
{
- }
-
- protected override void SetCacheAction(TId[] ids, TEntity[] entityCollection)
- {
- //no-op
+ // nop
}
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs
index b7b4ddd583..ca53b2e04e 100644
--- a/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs
@@ -2,19 +2,13 @@
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Cache;
-using Umbraco.Core.Events;
-using Umbraco.Core.Exceptions;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models.Rdbms;
-
-using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Querying;
-using Umbraco.Core.Persistence.Relators;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
-using Umbraco.Core.Services;
namespace Umbraco.Core.Persistence.Repositories
{
@@ -24,6 +18,7 @@ namespace Umbraco.Core.Persistence.Repositories
internal class ContentTypeRepository : ContentTypeBaseRepository, IContentTypeRepository
{
private readonly ITemplateRepository _templateRepository;
+ private IRepositoryCachePolicy _cachePolicy;
public ContentTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, ITemplateRepository templateRepository)
: base(work, cache, logger, sqlSyntax)
@@ -31,16 +26,11 @@ namespace Umbraco.Core.Persistence.Repositories
_templateRepository = templateRepository;
}
- private FullDataSetRepositoryCachePolicyFactory _cachePolicyFactory;
- protected override IRepositoryCachePolicyFactory CachePolicyFactory
+ protected override IRepositoryCachePolicy CachePolicy
{
get
{
- //Use a FullDataSet cache policy - this will cache the entire GetAll result in a single collection
- return _cachePolicyFactory ?? (_cachePolicyFactory = new FullDataSetRepositoryCachePolicyFactory(
- RuntimeCache, GetEntityId, () => PerformGetAll(),
- //allow this cache to expire
- expires:true));
+ return _cachePolicy ?? (_cachePolicy = new FullDataSetRepositoryCachePolicy(RuntimeCache, GetEntityId, /*expires:*/ true));
}
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/DictionaryRepository.cs b/src/Umbraco.Core/Persistence/Repositories/DictionaryRepository.cs
index 971efc4f2d..da6d4d94a8 100644
--- a/src/Umbraco.Core/Persistence/Repositories/DictionaryRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/DictionaryRepository.cs
@@ -20,24 +20,27 @@ namespace Umbraco.Core.Persistence.Repositories
///
internal class DictionaryRepository : PetaPocoRepositoryBase, IDictionaryRepository
{
+ private IRepositoryCachePolicy _cachePolicy;
+
public DictionaryRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider syntax)
: base(work, cache, logger, syntax)
- {
- }
+ { }
- private IRepositoryCachePolicyFactory _cachePolicyFactory;
- protected override IRepositoryCachePolicyFactory CachePolicyFactory
+ protected override IRepositoryCachePolicy CachePolicy
{
get
{
- //custom cache policy which will not cache any results for GetAll
- return _cachePolicyFactory ?? (_cachePolicyFactory = new OnlySingleItemsRepositoryCachePolicyFactory(
- RuntimeCache,
- new RepositoryCachePolicyOptions
- {
- //allow zero to be cached
- GetAllCacheAllowZeroCount = true
- }));
+ if (_cachePolicy != null) return _cachePolicy;
+
+ var options = new RepositoryCachePolicyOptions
+ {
+ //allow zero to be cached
+ GetAllCacheAllowZeroCount = true
+ };
+
+ _cachePolicy = new SingleItemsOnlyRepositoryCachePolicy(RuntimeCache, options);
+
+ return _cachePolicy;
}
}
@@ -52,7 +55,7 @@ namespace Umbraco.Core.Persistence.Repositories
var dto = Database.Fetch(new DictionaryLanguageTextRelator().Map, sql).FirstOrDefault();
if (dto == null)
return null;
-
+
var entity = ConvertFromDto(dto);
//on initial construction we don't want to have dirty properties tracked
@@ -80,7 +83,7 @@ namespace Umbraco.Core.Persistence.Repositories
var translator = new SqlTranslator(sqlClause, query);
var sql = translator.Translate();
sql.OrderBy(x => x.UniqueId, SqlSyntax);
-
+
return Database.Fetch(new DictionaryLanguageTextRelator().Map, sql)
.Select(x => ConvertFromDto(x));
}
@@ -149,7 +152,7 @@ namespace Umbraco.Core.Persistence.Repositories
translation.Key = dictionaryItem.Key;
}
- dictionaryItem.ResetDirtyProperties();
+ dictionaryItem.ResetDirtyProperties();
}
protected override void PersistUpdatedItem(IDictionaryItem entity)
@@ -223,7 +226,7 @@ namespace Umbraco.Core.Persistence.Repositories
var list = new List();
foreach (var textDto in dto.LanguageTextDtos)
- {
+ {
if (textDto.LanguageId <= 0)
continue;
@@ -250,7 +253,7 @@ namespace Umbraco.Core.Persistence.Repositories
return keyRepo.Get(key);
}
}
-
+
private IEnumerable GetRootDictionaryItems()
{
var query = Query.Builder.Where(x => x.ParentId == null);
@@ -291,6 +294,7 @@ namespace Umbraco.Core.Persistence.Repositories
private class DictionaryByUniqueIdRepository : SimpleGetRepository
{
+ private IRepositoryCachePolicy _cachePolicy;
private readonly DictionaryRepository _dictionaryRepository;
public DictionaryByUniqueIdRepository(DictionaryRepository dictionaryRepository, IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
@@ -329,25 +333,28 @@ namespace Umbraco.Core.Persistence.Repositories
return "cmsDictionary." + SqlSyntax.GetQuotedColumnName("id") + " in (@ids)";
}
- private IRepositoryCachePolicyFactory _cachePolicyFactory;
- protected override IRepositoryCachePolicyFactory CachePolicyFactory
+ protected override IRepositoryCachePolicy CachePolicy
{
get
{
- //custom cache policy which will not cache any results for GetAll
- return _cachePolicyFactory ?? (_cachePolicyFactory = new OnlySingleItemsRepositoryCachePolicyFactory(
- RuntimeCache,
- new RepositoryCachePolicyOptions
- {
- //allow zero to be cached
- GetAllCacheAllowZeroCount = true
- }));
+ if (_cachePolicy != null) return _cachePolicy;
+
+ var options = new RepositoryCachePolicyOptions
+ {
+ //allow zero to be cached
+ GetAllCacheAllowZeroCount = true
+ };
+
+ _cachePolicy = new SingleItemsOnlyRepositoryCachePolicy(RuntimeCache, options);
+
+ return _cachePolicy;
}
}
}
private class DictionaryByKeyRepository : SimpleGetRepository
{
+ private IRepositoryCachePolicy _cachePolicy;
private readonly DictionaryRepository _dictionaryRepository;
public DictionaryByKeyRepository(DictionaryRepository dictionaryRepository, IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
@@ -386,23 +393,23 @@ namespace Umbraco.Core.Persistence.Repositories
return "cmsDictionary." + SqlSyntax.GetQuotedColumnName("key") + " in (@ids)";
}
- private IRepositoryCachePolicyFactory _cachePolicyFactory;
- protected override IRepositoryCachePolicyFactory CachePolicyFactory
+ protected override IRepositoryCachePolicy CachePolicy
{
get
{
- //custom cache policy which will not cache any results for GetAll
- return _cachePolicyFactory ?? (_cachePolicyFactory = new OnlySingleItemsRepositoryCachePolicyFactory(
- RuntimeCache,
- new RepositoryCachePolicyOptions
- {
- //allow zero to be cached
- GetAllCacheAllowZeroCount = true
- }));
+ if (_cachePolicy != null) return _cachePolicy;
+
+ var options = new RepositoryCachePolicyOptions
+ {
+ //allow zero to be cached
+ GetAllCacheAllowZeroCount = true
+ };
+
+ _cachePolicy = new SingleItemsOnlyRepositoryCachePolicy(RuntimeCache, options);
+
+ return _cachePolicy;
}
}
}
-
-
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Repositories/DomainRepository.cs b/src/Umbraco.Core/Persistence/Repositories/DomainRepository.cs
index 7b6cc162a8..682c75eeb6 100644
--- a/src/Umbraco.Core/Persistence/Repositories/DomainRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/DomainRepository.cs
@@ -18,19 +18,22 @@ namespace Umbraco.Core.Persistence.Repositories
internal class DomainRepository : PetaPocoRepositoryBase, IDomainRepository
{
+ private IRepositoryCachePolicy _cachePolicy;
+
public DomainRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{
}
- private FullDataSetRepositoryCachePolicyFactory _cachePolicyFactory;
- protected override IRepositoryCachePolicyFactory CachePolicyFactory
+ protected override IRepositoryCachePolicy CachePolicy
{
get
{
- //Use a FullDataSet cache policy - this will cache the entire GetAll result in a single collection
- return _cachePolicyFactory ?? (_cachePolicyFactory = new FullDataSetRepositoryCachePolicyFactory(
- RuntimeCache, GetEntityId, () => PerformGetAll(), false));
+ if (_cachePolicy != null) return _cachePolicy;
+
+ _cachePolicy = new FullDataSetRepositoryCachePolicy(RuntimeCache, GetEntityId, /*expires:*/ false);
+
+ return _cachePolicy;
}
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/LanguageRepository.cs b/src/Umbraco.Core/Persistence/Repositories/LanguageRepository.cs
index f9a8e59cfa..7911df8edb 100644
--- a/src/Umbraco.Core/Persistence/Repositories/LanguageRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/LanguageRepository.cs
@@ -19,19 +19,22 @@ namespace Umbraco.Core.Persistence.Repositories
///
internal class LanguageRepository : PetaPocoRepositoryBase, ILanguageRepository
{
+ private IRepositoryCachePolicy _cachePolicy;
+
public LanguageRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{
}
- private FullDataSetRepositoryCachePolicyFactory _cachePolicyFactory;
- protected override IRepositoryCachePolicyFactory CachePolicyFactory
+ protected override IRepositoryCachePolicy CachePolicy
{
get
{
- //Use a FullDataSet cache policy - this will cache the entire GetAll result in a single collection
- return _cachePolicyFactory ?? (_cachePolicyFactory = new FullDataSetRepositoryCachePolicyFactory(
- RuntimeCache, GetEntityId, () => PerformGetAll(), false));
+ if (_cachePolicy != null) return _cachePolicy;
+
+ _cachePolicy = new FullDataSetRepositoryCachePolicy(RuntimeCache, GetEntityId, /*expires:*/ false);
+
+ return _cachePolicy;
}
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs
index 50a89bfd65..516c08330a 100644
--- a/src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs
@@ -22,22 +22,22 @@ namespace Umbraco.Core.Persistence.Repositories
///
internal class MediaTypeRepository : ContentTypeBaseRepository, IMediaTypeRepository
{
+ private IRepositoryCachePolicy _cachePolicy;
public MediaTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{
}
- private FullDataSetRepositoryCachePolicyFactory _cachePolicyFactory;
- protected override IRepositoryCachePolicyFactory CachePolicyFactory
+ protected override IRepositoryCachePolicy CachePolicy
{
get
{
- //Use a FullDataSet cache policy - this will cache the entire GetAll result in a single collection
- return _cachePolicyFactory ?? (_cachePolicyFactory = new FullDataSetRepositoryCachePolicyFactory(
- RuntimeCache, GetEntityId, () => PerformGetAll(),
- //allow this cache to expire
- expires: true));
+ if (_cachePolicy != null) return _cachePolicy;
+
+ _cachePolicy = new FullDataSetRepositoryCachePolicy(RuntimeCache, GetEntityId, /*expires:*/ true);
+
+ return _cachePolicy;
}
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs
index 7d5defe8c9..fd26afac89 100644
--- a/src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs
@@ -21,25 +21,25 @@ namespace Umbraco.Core.Persistence.Repositories
///
internal class MemberTypeRepository : ContentTypeBaseRepository, IMemberTypeRepository
{
+ private IRepositoryCachePolicy _cachePolicy;
public MemberTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{
}
- private FullDataSetRepositoryCachePolicyFactory _cachePolicyFactory;
- protected override IRepositoryCachePolicyFactory CachePolicyFactory
+ protected override IRepositoryCachePolicy CachePolicy
{
get
{
- //Use a FullDataSet cache policy - this will cache the entire GetAll result in a single collection
- return _cachePolicyFactory ?? (_cachePolicyFactory = new FullDataSetRepositoryCachePolicyFactory(
- RuntimeCache, GetEntityId, () => PerformGetAll(),
- //allow this cache to expire
- expires: true));
+ if (_cachePolicy != null) return _cachePolicy;
+
+ _cachePolicy = new FullDataSetRepositoryCachePolicy(RuntimeCache, GetEntityId, /*expires:*/ true);
+
+ return _cachePolicy;
}
}
-
+
protected override IMemberType PerformGet(int id)
{
//use the underlying GetAll which will force cache all content types
diff --git a/src/Umbraco.Core/Persistence/Repositories/PetaPocoRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/PetaPocoRepositoryBase.cs
index fe363fea16..c02316e7f4 100644
--- a/src/Umbraco.Core/Persistence/Repositories/PetaPocoRepositoryBase.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/PetaPocoRepositoryBase.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Data.SqlServerCe;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.EntityBase;
diff --git a/src/Umbraco.Core/Persistence/Repositories/PublicAccessRepository.cs b/src/Umbraco.Core/Persistence/Repositories/PublicAccessRepository.cs
index 37200b2172..c34952f4be 100644
--- a/src/Umbraco.Core/Persistence/Repositories/PublicAccessRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/PublicAccessRepository.cs
@@ -15,18 +15,21 @@ namespace Umbraco.Core.Persistence.Repositories
{
internal class PublicAccessRepository : PetaPocoRepositoryBase, IPublicAccessRepository
{
+ private IRepositoryCachePolicy _cachePolicy;
+
public PublicAccessRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{ }
- private FullDataSetRepositoryCachePolicyFactory _cachePolicyFactory;
- protected override IRepositoryCachePolicyFactory CachePolicyFactory
+ protected override IRepositoryCachePolicy CachePolicy
{
get
{
- //Use a FullDataSet cache policy - this will cache the entire GetAll result in a single collection
- return _cachePolicyFactory ?? (_cachePolicyFactory = new FullDataSetRepositoryCachePolicyFactory(
- RuntimeCache, GetEntityId, () => PerformGetAll(), false));
+ if (_cachePolicy != null) return _cachePolicy;
+
+ _cachePolicy = new FullDataSetRepositoryCachePolicy(RuntimeCache, GetEntityId, /*expires:*/ false);
+
+ return _cachePolicy;
}
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/RelationTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/RelationTypeRepository.cs
index 2c54897ff7..148ebba456 100644
--- a/src/Umbraco.Core/Persistence/Repositories/RelationTypeRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/RelationTypeRepository.cs
@@ -19,20 +19,21 @@ namespace Umbraco.Core.Persistence.Repositories
///
internal class RelationTypeRepository : PetaPocoRepositoryBase, IRelationTypeRepository
{
+ private IRepositoryCachePolicy _cachePolicy;
+
public RelationTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{ }
- // assuming we don't have tons of relation types, use a FullDataSet policy, ie
- // cache the entire GetAll result once in a single collection - which can expire
- private FullDataSetRepositoryCachePolicyFactory _cachePolicyFactory;
- protected override IRepositoryCachePolicyFactory CachePolicyFactory
+ protected override IRepositoryCachePolicy CachePolicy
{
get
{
- return _cachePolicyFactory
- ?? (_cachePolicyFactory = new FullDataSetRepositoryCachePolicyFactory(
- RuntimeCache, GetEntityId, () => PerformGetAll(), expires: true));
+ if (_cachePolicy != null) return _cachePolicy;
+
+ _cachePolicy = new FullDataSetRepositoryCachePolicy(RuntimeCache, GetEntityId, /*expires:*/ true);
+
+ return _cachePolicy;
}
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs
index 41946d48d4..201520cbe3 100644
--- a/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs
@@ -82,7 +82,6 @@ namespace Umbraco.Core.Persistence.Repositories
{
}
-
#region Static Queries
private IQuery _hasIdQuery;
@@ -102,30 +101,25 @@ namespace Umbraco.Core.Persistence.Repositories
get { return RepositoryCache.IsolatedRuntimeCache.GetOrCreateCache(); }
}
- private IRepositoryCachePolicyFactory _cachePolicyFactory;
- ///
- /// Returns the Cache Policy for the repository
- ///
- ///
- /// The Cache Policy determines how each entity or entity collection is cached
- ///
- protected virtual IRepositoryCachePolicyFactory CachePolicyFactory
+ private IRepositoryCachePolicy _cachePolicy;
+
+ protected virtual IRepositoryCachePolicy CachePolicy
{
get
{
- return _cachePolicyFactory ?? (_cachePolicyFactory = new DefaultRepositoryCachePolicyFactory(
- RuntimeCache,
- new RepositoryCachePolicyOptions(() =>
- {
- //create it once if it is needed (no need for locking here)
- if (_hasIdQuery == null)
- {
- _hasIdQuery = Query.Builder.Where(x => x.Id != 0);
- }
+ if (_cachePolicy != null) return _cachePolicy;
- //Get count of all entities of current type (TEntity) to ensure cached result is correct
- return PerformCount(_hasIdQuery);
- })));
+ var options = new RepositoryCachePolicyOptions(() =>
+ {
+ //Get count of all entities of current type (TEntity) to ensure cached result is correct
+ //create query once if it is needed (no need for locking here)
+ var query = _hasIdQuery ?? (_hasIdQuery = Query.Builder.Where(x => x.Id != 0));
+ return PerformCount(query);
+ });
+
+ _cachePolicy = new DefaultRepositoryCachePolicy(RuntimeCache, options);
+
+ return _cachePolicy;
}
}
@@ -166,10 +160,7 @@ namespace Umbraco.Core.Persistence.Repositories
///
public TEntity Get(TId id)
{
- using (var p = CachePolicyFactory.CreatePolicy())
- {
- return p.Get(id, PerformGet);
- }
+ return CachePolicy.Get(id, PerformGet, PerformGetAll);
}
protected abstract IEnumerable PerformGetAll(params TId[] ids);
@@ -192,13 +183,9 @@ namespace Umbraco.Core.Persistence.Repositories
throw new InvalidOperationException("Cannot perform a query with more than 2000 parameters");
}
- using (var p = CachePolicyFactory.CreatePolicy())
- {
- var result = p.GetAll(ids, PerformGetAll);
- return result;
- }
+ return CachePolicy.GetAll(ids, PerformGetAll);
}
-
+
protected abstract IEnumerable PerformGetByQuery(IQuery query);
///
/// Gets a list of entities by the passed in query
@@ -220,10 +207,7 @@ namespace Umbraco.Core.Persistence.Repositories
///
public bool Exists(TId id)
{
- using (var p = CachePolicyFactory.CreatePolicy())
- {
- return p.Exists(id, PerformExists);
- }
+ return CachePolicy.Exists(id, PerformExists, PerformGetAll);
}
protected abstract int PerformCount(IQuery query);
@@ -236,19 +220,14 @@ namespace Umbraco.Core.Persistence.Repositories
{
return PerformCount(query);
}
-
+
///
/// Unit of work method that tells the repository to persist the new entity
///
///
public virtual void PersistNewItem(IEntity entity)
{
- var casted = (TEntity)entity;
-
- using (var p = CachePolicyFactory.CreatePolicy())
- {
- p.CreateOrUpdate(casted, PersistNewItem);
- }
+ CachePolicy.Create((TEntity) entity, PersistNewItem);
}
///
@@ -257,12 +236,7 @@ namespace Umbraco.Core.Persistence.Repositories
///
public virtual void PersistUpdatedItem(IEntity entity)
{
- var casted = (TEntity)entity;
-
- using (var p = CachePolicyFactory.CreatePolicy())
- {
- p.CreateOrUpdate(casted, PersistUpdatedItem);
- }
+ CachePolicy.Update((TEntity) entity, PersistUpdatedItem);
}
///
@@ -271,20 +245,13 @@ namespace Umbraco.Core.Persistence.Repositories
///
public virtual void PersistDeletedItem(IEntity entity)
{
- var casted = (TEntity)entity;
-
- using (var p = CachePolicyFactory.CreatePolicy())
- {
- p.Remove(casted, PersistDeletedItem);
- }
+ CachePolicy.Delete((TEntity) entity, PersistDeletedItem);
}
-
protected abstract void PersistNewItem(TEntity item);
protected abstract void PersistUpdatedItem(TEntity item);
protected abstract void PersistDeletedItem(TEntity item);
-
///
/// Dispose disposable properties
///
diff --git a/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs b/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs
index 41743601fb..a164e7e5ba 100644
--- a/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs
@@ -33,6 +33,7 @@ namespace Umbraco.Core.Persistence.Repositories
private readonly ITemplatesSection _templateConfig;
private readonly ViewHelper _viewHelper;
private readonly MasterPageHelper _masterPageHelper;
+ private IRepositoryCachePolicy _cachePolicy;
internal TemplateRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IFileSystem masterpageFileSystem, IFileSystem viewFileSystem, ITemplatesSection templateConfig)
: base(work, cache, logger, sqlSyntax)
@@ -45,14 +46,15 @@ namespace Umbraco.Core.Persistence.Repositories
}
- private FullDataSetRepositoryCachePolicyFactory _cachePolicyFactory;
- protected override IRepositoryCachePolicyFactory CachePolicyFactory
+ protected override IRepositoryCachePolicy CachePolicy
{
get
{
- //Use a FullDataSet cache policy - this will cache the entire GetAll result in a single collection
- return _cachePolicyFactory ?? (_cachePolicyFactory = new FullDataSetRepositoryCachePolicyFactory(
- RuntimeCache, GetEntityId, () => PerformGetAll(), false));
+ if (_cachePolicy != null) return _cachePolicy;
+
+ _cachePolicy = new FullDataSetRepositoryCachePolicy(RuntimeCache, GetEntityId, /*expires:*/ false);
+
+ return _cachePolicy;
}
}
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index afa85609d0..fc778bc53b 100644
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -136,9 +136,7 @@
-
-
@@ -146,7 +144,6 @@
-
@@ -156,7 +153,6 @@
-
diff --git a/src/Umbraco.Tests/Cache/DefaultCachePolicyTests.cs b/src/Umbraco.Tests/Cache/DefaultCachePolicyTests.cs
index 9b0aaac78b..83b0db237f 100644
--- a/src/Umbraco.Tests/Cache/DefaultCachePolicyTests.cs
+++ b/src/Umbraco.Tests/Cache/DefaultCachePolicyTests.cs
@@ -24,10 +24,8 @@ namespace Umbraco.Tests.Cache
});
var defaultPolicy = new DefaultRepositoryCachePolicy(cache.Object, new RepositoryCachePolicyOptions());
- using (defaultPolicy)
- {
- var found = defaultPolicy.Get(1, o => new AuditItem(1, "blah", AuditType.Copy, 123));
- }
+
+ var found = defaultPolicy.Get(1, id => new AuditItem(1, "blah", AuditType.Copy, 123), o => null);
Assert.IsTrue(isCached);
}
@@ -38,11 +36,9 @@ namespace Umbraco.Tests.Cache
cache.Setup(x => x.GetCacheItem(It.IsAny())).Returns(new AuditItem(1, "blah", AuditType.Copy, 123));
var defaultPolicy = new DefaultRepositoryCachePolicy(cache.Object, new RepositoryCachePolicyOptions());
- using (defaultPolicy)
- {
- var found = defaultPolicy.Get(1, o => (AuditItem) null);
- Assert.IsNotNull(found);
- }
+
+ var found = defaultPolicy.Get(1, id => null, ids => null);
+ Assert.IsNotNull(found);
}
[Test]
@@ -59,14 +55,12 @@ namespace Umbraco.Tests.Cache
cache.Setup(x => x.GetCacheItemsByKeySearch(It.IsAny())).Returns(new AuditItem[] {});
var defaultPolicy = new DefaultRepositoryCachePolicy(cache.Object, new RepositoryCachePolicyOptions());
- using (defaultPolicy)
+
+ var found = defaultPolicy.GetAll(new object[] { }, ids => new[]
{
- var found = defaultPolicy.GetAll(new object[] {}, o => new[]
- {
- new AuditItem(1, "blah", AuditType.Copy, 123),
- new AuditItem(2, "blah2", AuditType.Copy, 123)
- });
- }
+ new AuditItem(1, "blah", AuditType.Copy, 123),
+ new AuditItem(2, "blah2", AuditType.Copy, 123)
+ });
Assert.AreEqual(2, cached.Count);
}
@@ -82,11 +76,9 @@ namespace Umbraco.Tests.Cache
});
var defaultPolicy = new DefaultRepositoryCachePolicy(cache.Object, new RepositoryCachePolicyOptions());
- using (defaultPolicy)
- {
- var found = defaultPolicy.GetAll(new object[] {}, o => new[] {(AuditItem) null});
- Assert.AreEqual(2, found.Length);
- }
+
+ var found = defaultPolicy.GetAll(new object[] { }, ids => new[] { (AuditItem)null });
+ Assert.AreEqual(2, found.Length);
}
[Test]
@@ -103,13 +95,7 @@ namespace Umbraco.Tests.Cache
var defaultPolicy = new DefaultRepositoryCachePolicy(cache.Object, new RepositoryCachePolicyOptions());
try
{
- using (defaultPolicy)
- {
- defaultPolicy.CreateOrUpdate(new AuditItem(1, "blah", AuditType.Copy, 123), item =>
- {
- throw new Exception("blah!");
- });
- }
+ defaultPolicy.Update(new AuditItem(1, "blah", AuditType.Copy, 123), item => { throw new Exception("blah!"); });
}
catch
{
@@ -135,13 +121,7 @@ namespace Umbraco.Tests.Cache
var defaultPolicy = new DefaultRepositoryCachePolicy(cache.Object, new RepositoryCachePolicyOptions());
try
{
- using (defaultPolicy)
- {
- defaultPolicy.Remove(new AuditItem(1, "blah", AuditType.Copy, 123), item =>
- {
- throw new Exception("blah!");
- });
- }
+ defaultPolicy.Delete(new AuditItem(1, "blah", AuditType.Copy, 123), item => { throw new Exception("blah!"); });
}
catch
{
diff --git a/src/Umbraco.Tests/Cache/FullDataSetCachePolicyTests.cs b/src/Umbraco.Tests/Cache/FullDataSetCachePolicyTests.cs
index 96e22e3aff..ee519afb76 100644
--- a/src/Umbraco.Tests/Cache/FullDataSetCachePolicyTests.cs
+++ b/src/Umbraco.Tests/Cache/FullDataSetCachePolicyTests.cs
@@ -32,11 +32,9 @@ namespace Umbraco.Tests.Cache
isCached = true;
});
- var defaultPolicy = new FullDataSetRepositoryCachePolicy(cache.Object, item => item.Id, () => getAll, false);
- using (defaultPolicy)
- {
- var found = defaultPolicy.Get(1, o => new AuditItem(1, "blah", AuditType.Copy, 123));
- }
+ var policy = new FullDataSetRepositoryCachePolicy(cache.Object, item => item.Id, false);
+
+ var found = policy.Get(1, id => new AuditItem(1, "blah", AuditType.Copy, 123), ids => getAll);
Assert.IsTrue(isCached);
}
@@ -52,12 +50,10 @@ namespace Umbraco.Tests.Cache
var cache = new Mock();
cache.Setup(x => x.GetCacheItem(It.IsAny())).Returns(new AuditItem(1, "blah", AuditType.Copy, 123));
- var defaultPolicy = new FullDataSetRepositoryCachePolicy(cache.Object, item => item.Id, () => getAll, false);
- using (defaultPolicy)
- {
- var found = defaultPolicy.Get(1, o => (AuditItem)null);
- Assert.IsNotNull(found);
- }
+ var defaultPolicy = new FullDataSetRepositoryCachePolicy(cache.Object, item => item.Id, false);
+
+ var found = defaultPolicy.Get(1, id => null, ids => getAll);
+ Assert.IsNotNull(found);
}
[Test]
@@ -84,21 +80,17 @@ namespace Umbraco.Tests.Cache
return cached.Any() ? new DeepCloneableList(ListCloneBehavior.CloneOnce) : null;
});
- var defaultPolicy = new FullDataSetRepositoryCachePolicy(cache.Object, item => item.Id, () => getAll, false);
- using (defaultPolicy)
- {
- var found = defaultPolicy.GetAll(new object[] {}, o => getAll);
- }
+ var policy = new FullDataSetRepositoryCachePolicy(cache.Object, item => item.Id, false);
+
+ var found = policy.GetAll(new object[] { }, ids => getAll);
Assert.AreEqual(1, cached.Count);
Assert.IsNotNull(list);
//Do it again, ensure that its coming from the cache!
- defaultPolicy = new FullDataSetRepositoryCachePolicy(cache.Object, item => item.Id, () => getAll, false);
- using (defaultPolicy)
- {
- var found = defaultPolicy.GetAll(new object[] { }, o => getAll);
- }
+ policy = new FullDataSetRepositoryCachePolicy(cache.Object, item => item.Id, false);
+
+ found = policy.GetAll(new object[] { }, ids => getAll);
Assert.AreEqual(1, cached.Count);
Assert.IsNotNull(list);
@@ -127,11 +119,9 @@ namespace Umbraco.Tests.Cache
});
cache.Setup(x => x.GetCacheItem(It.IsAny())).Returns(new AuditItem[] { });
- var defaultPolicy = new FullDataSetRepositoryCachePolicy(cache.Object, item => item.Id, () => getAll, false);
- using (defaultPolicy)
- {
- var found = defaultPolicy.GetAll(new object[] { }, o => getAll);
- }
+ var defaultPolicy = new FullDataSetRepositoryCachePolicy(cache.Object, item => item.Id, false);
+
+ var found = defaultPolicy.GetAll(new object[] { }, ids => getAll);
Assert.AreEqual(1, cached.Count);
Assert.IsNotNull(list);
@@ -150,12 +140,10 @@ namespace Umbraco.Tests.Cache
new AuditItem(2, "blah2", AuditType.Copy, 123)
});
- var defaultPolicy = new FullDataSetRepositoryCachePolicy(cache.Object, item => item.Id, () => getAll, false);
- using (defaultPolicy)
- {
- var found = defaultPolicy.GetAll(new object[] { }, o => getAll);
- Assert.AreEqual(2, found.Length);
- }
+ var defaultPolicy = new FullDataSetRepositoryCachePolicy(cache.Object, item => item.Id, false);
+
+ var found = defaultPolicy.GetAll(new object[] { }, ids => getAll);
+ Assert.AreEqual(2, found.Length);
}
[Test]
@@ -175,16 +163,10 @@ namespace Umbraco.Tests.Cache
cacheCleared = true;
});
- var defaultPolicy = new FullDataSetRepositoryCachePolicy(cache.Object, item => item.Id, () => getAll, false);
+ var defaultPolicy = new FullDataSetRepositoryCachePolicy(cache.Object, item => item.Id, false);
try
{
- using (defaultPolicy)
- {
- defaultPolicy.CreateOrUpdate(new AuditItem(1, "blah", AuditType.Copy, 123), item =>
- {
- throw new Exception("blah!");
- });
- }
+ defaultPolicy.Update(new AuditItem(1, "blah", AuditType.Copy, 123), item => { throw new Exception("blah!"); });
}
catch
{
@@ -213,16 +195,10 @@ namespace Umbraco.Tests.Cache
cacheCleared = true;
});
- var defaultPolicy = new FullDataSetRepositoryCachePolicy(cache.Object, item => item.Id, () => getAll, false);
+ var defaultPolicy = new FullDataSetRepositoryCachePolicy(cache.Object, item => item.Id, false);
try
{
- using (defaultPolicy)
- {
- defaultPolicy.Remove(new AuditItem(1, "blah", AuditType.Copy, 123), item =>
- {
- throw new Exception("blah!");
- });
- }
+ defaultPolicy.Delete(new AuditItem(1, "blah", AuditType.Copy, 123), item => { throw new Exception("blah!"); });
}
catch
{
diff --git a/src/Umbraco.Tests/Cache/SingleItemsOnlyCachePolicyTests.cs b/src/Umbraco.Tests/Cache/SingleItemsOnlyCachePolicyTests.cs
index b8e77e9267..55a7f2a893 100644
--- a/src/Umbraco.Tests/Cache/SingleItemsOnlyCachePolicyTests.cs
+++ b/src/Umbraco.Tests/Cache/SingleItemsOnlyCachePolicyTests.cs
@@ -25,14 +25,12 @@ namespace Umbraco.Tests.Cache
cache.Setup(x => x.GetCacheItemsByKeySearch(It.IsAny())).Returns(new AuditItem[] { });
var defaultPolicy = new SingleItemsOnlyRepositoryCachePolicy(cache.Object, new RepositoryCachePolicyOptions());
- using (defaultPolicy)
+
+ var found = defaultPolicy.GetAll(new object[] { }, ids => new[]
{
- var found = defaultPolicy.GetAll(new object[] { }, o => new[]
- {
- new AuditItem(1, "blah", AuditType.Copy, 123),
- new AuditItem(2, "blah2", AuditType.Copy, 123)
- });
- }
+ new AuditItem(1, "blah", AuditType.Copy, 123),
+ new AuditItem(2, "blah2", AuditType.Copy, 123)
+ });
Assert.AreEqual(0, cached.Count);
}
@@ -50,10 +48,8 @@ namespace Umbraco.Tests.Cache
});
var defaultPolicy = new SingleItemsOnlyRepositoryCachePolicy(cache.Object, new RepositoryCachePolicyOptions());
- using (defaultPolicy)
- {
- var found = defaultPolicy.Get(1, o => new AuditItem(1, "blah", AuditType.Copy, 123));
- }
+
+ var found = defaultPolicy.Get(1, id => new AuditItem(1, "blah", AuditType.Copy, 123), ids => null);
Assert.IsTrue(isCached);
}
}