diff --git a/src/Umbraco.Core/Cache/DefaultRepositoryCachePolicy.cs b/src/Umbraco.Core/Cache/DefaultRepositoryCachePolicy.cs
index 1f0bc85e2c..0d601fbea6 100644
--- a/src/Umbraco.Core/Cache/DefaultRepositoryCachePolicy.cs
+++ b/src/Umbraco.Core/Cache/DefaultRepositoryCachePolicy.cs
@@ -40,158 +40,155 @@ namespace Umbraco.Core.Cache
return $"uRepo_{typeof (TEntity).Name}_";
}
- ///
- /// Sets the action to execute on disposal for a single entity
- ///
- ///
- ///
- protected virtual void SetCacheActionToInsertEntity(string cacheKey, TEntity entity)
+ protected virtual void InsertEntity(string cacheKey, TEntity entity)
{
- SetCacheAction(() =>
- {
- Cache.InsertCacheItem(cacheKey, () => entity, TimeSpan.FromMinutes(5), true);
- });
+ Cache.InsertCacheItem(cacheKey, () => entity, TimeSpan.FromMinutes(5), true);
}
- ///
- /// Sets the action to execute on disposal for an entity collection
- ///
- ///
- ///
- protected virtual void SetCacheActionToInsertEntities(TId[] ids, TEntity[] entities)
+ protected virtual void InsertEntities(TId[] ids, TEntity[] entities)
{
- SetCacheAction(() =>
+ if (ids.Length == 0 && entities.Length == 0 && _options.GetAllCacheAllowZeroCount)
{
- 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)
{
- // 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);
+ var capture = entity;
+ Cache.InsertCacheItem(GetEntityCacheKey(entity.Id), () => capture, TimeSpan.FromMinutes(5), true);
}
- 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 CreateOrUpdate(TEntity entity, Action repoCreateOrUpdate)
+ public override void Create(TEntity entity, Action persistNew)
{
if (entity == null) throw new ArgumentNullException(nameof(entity));
- if (repoCreateOrUpdate == null) throw new ArgumentNullException(nameof(repoCreateOrUpdate));
try
{
- repoCreateOrUpdate(entity);
+ persistNew(entity);
- 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(GetEntityCacheKey(entity.Id), () => entity, TimeSpan.FromMinutes(5), true);
- }
-
- // if there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
- Cache.ClearCacheItem(GetEntityTypeCacheKey());
- });
+ Cache.InsertCacheItem(GetEntityCacheKey(entity.Id), () => entity, TimeSpan.FromMinutes(5), true);
+ }
+ // if there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
+ Cache.ClearCacheItem(GetEntityTypeCacheKey());
}
catch
{
- 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(GetEntityCacheKey(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(GetEntityTypeCacheKey());
throw;
}
}
///
- public override void Remove(TEntity entity, Action repoRemove)
+ public override void Update(TEntity entity, Action persistUpdated)
{
if (entity == null) throw new ArgumentNullException(nameof(entity));
- if (repoRemove == null) throw new ArgumentNullException(nameof(repoRemove));
try
{
- repoRemove(entity);
+ persistUpdated(entity);
+
+ // just to be safe, we cannot cache an item without an identity
+ if (entity.HasIdentity)
+ {
+ 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 void Delete(TEntity entity, Action persistDeleted)
+ {
+ if (entity == null) throw new ArgumentNullException(nameof(entity));
+
+ try
+ {
+ persistDeleted(entity);
}
finally
{
// whatever happens, clear the cache
var cacheKey = GetEntityCacheKey(entity.Id);
- SetCacheAction(() =>
- {
- Cache.ClearCacheItem(cacheKey);
-
- // if there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
- Cache.ClearCacheItem(GetEntityTypeCacheKey());
- });
+ Cache.ClearCacheItem(cacheKey);
+ // if there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
+ Cache.ClearCacheItem(GetEntityTypeCacheKey());
}
}
///
- public override TEntity Get(TId id, Func repoGet)
+ public override TEntity Get(TId id, Func performGet, Func> performGetAll)
{
- if (repoGet == null) throw new ArgumentNullException(nameof(repoGet));
-
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 = repoGet(id);
+ var entity = performGet(id);
if (entity != null && entity.HasIdentity)
- SetCacheActionToInsertEntity(cacheKey, entity);
+ InsertEntity(cacheKey, entity);
return entity;
}
///
- public override TEntity Get(TId id)
+ public override TEntity GetCached(TId id)
{
var cacheKey = GetEntityCacheKey(id);
return Cache.GetCacheItem(cacheKey);
}
///
- public override bool Exists(TId id, Func repoExists)
+ public override bool Exists(TId id, Func performExists, Func> performGetAll)
{
- if (repoExists == null) throw new ArgumentNullException(nameof(repoExists));
-
// if found in cache the return else check
var cacheKey = GetEntityCacheKey(id);
var fromCache = Cache.GetCacheItem(cacheKey);
- return fromCache != null || repoExists(id);
+ return fromCache != null || performExists(id);
}
///
- public override TEntity[] GetAll(TId[] ids, Func> repoGet)
+ public override TEntity[] GetAll(TId[] ids, Func> performGetAll)
{
- if (repoGet == null) throw new ArgumentNullException(nameof(repoGet));
-
if (ids.Length > 0)
{
// try to get each entity from the cache
// if we can find all of them, return
- var entities = ids.Select(Get).ToArray();
+ 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
}
@@ -227,15 +224,21 @@ namespace Umbraco.Core.Cache
}
// cache failed, get from repo and cache
- var repoEntities = repoGet(ids)
+ var repoEntities = performGetAll(ids)
.WhereNotNull() // exclude nulls!
.Where(x => x.HasIdentity) // be safe, though would be weird...
.ToArray();
// note: if empty & allow zero count, will cache a special (empty) entry
- SetCacheActionToInsertEntities(ids, repoEntities);
+ InsertEntities(ids, repoEntities);
return repoEntities;
}
+
+ ///
+ public override void ClearAll()
+ {
+ Cache.ClearCacheByKeySearch(GetEntityTypeCacheKey());
+ }
}
}
\ 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 93780f8f2e..26d81830c0 100644
--- a/src/Umbraco.Core/Cache/FullDataSetRepositoryCachePolicy.cs
+++ b/src/Umbraco.Core/Cache/FullDataSetRepositoryCachePolicy.cs
@@ -21,120 +21,129 @@ namespace Umbraco.Core.Cache
where TEntity : class, IAggregateRoot
{
private readonly Func _entityGetId;
- private readonly Func> _repoGetAll;
private readonly bool _expires;
- public FullDataSetRepositoryCachePolicy(IRuntimeCacheProvider cache, Func entityGetId, Func> repoGetAll, bool expires)
+ public FullDataSetRepositoryCachePolicy(IRuntimeCacheProvider cache,
+ Func entityGetId,
+ bool expires)
: base(cache)
{
_entityGetId = entityGetId;
- _repoGetAll = repoGetAll;
_expires = expires;
}
+ protected static readonly TId[] EmptyIds = new TId[0];
+
protected string GetEntityTypeCacheKey()
{
return $"uRepo_{typeof (TEntity).Name}_";
}
- private void SetCacheActionToClearAll()
+ protected void InsertEntities(TEntity[] entities)
{
- SetCacheAction(() =>
- {
- // clear all, force reload
- Cache.ClearCacheItem(GetEntityTypeCacheKey());
- });
- }
+ // 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.
- protected void SetCacheActionToInsertEntities(TEntity[] entities)
- {
- SetCacheAction(() =>
+ if (_expires)
{
- // 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.
-
- if (_expires)
- {
- Cache.InsertCacheItem(GetEntityTypeCacheKey(), () => new DeepCloneableList(entities), TimeSpan.FromMinutes(5), true);
- }
- else
- {
- Cache.InsertCacheItem(GetEntityTypeCacheKey(), () => new DeepCloneableList(entities));
- }
- });
+ Cache.InsertCacheItem(GetEntityTypeCacheKey(), () => new DeepCloneableList(entities), TimeSpan.FromMinutes(5), true);
+ }
+ else
+ {
+ Cache.InsertCacheItem(GetEntityTypeCacheKey(), () => new DeepCloneableList(entities));
+ }
}
///
- public override void CreateOrUpdate(TEntity entity, Action repoCreateOrUpdate)
+ public override void Create(TEntity entity, Action persistNew)
{
if (entity == null) throw new ArgumentNullException(nameof(entity));
- if (repoCreateOrUpdate == null) throw new ArgumentNullException(nameof(repoCreateOrUpdate));
try
{
- repoCreateOrUpdate(entity);
+ persistNew(entity);
}
finally
{
- SetCacheActionToClearAll();
+ ClearAll();
}
}
///
- public override void Remove(TEntity entity, Action repoRemove)
+ public override void Update(TEntity entity, Action persistUpdated)
{
if (entity == null) throw new ArgumentNullException(nameof(entity));
- if (repoRemove == null) throw new ArgumentNullException(nameof(repoRemove));
try
{
- repoRemove(entity);
+ persistUpdated(entity);
}
finally
{
- SetCacheActionToClearAll();
+ ClearAll();
}
}
///
- public override TEntity Get(TId id, Func repoGet)
+ public override void Delete(TEntity entity, Action persistDeleted)
{
- return Get(id);
+ if (entity == null) throw new ArgumentNullException(nameof(entity));
+
+ try
+ {
+ persistDeleted(entity);
+ }
+ finally
+ {
+ ClearAll();
+ }
}
///
- public override TEntity Get(TId id)
+ public override TEntity Get(TId id, Func performGet, Func> performGetAll)
{
- // get all from the cache, the look for the entity
- var all = GetAllCached();
+ // get all from the cache, then look for the entity
+ var all = GetAllCached(performGetAll);
var entity = all.FirstOrDefault(x => _entityGetId(x).Equals(id));
- // see note in SetCacheActionToInsertEntities - what we get here is the original
+ // 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 (TEntity)entity?.DeepClone();
+ }
+
+ ///
+ public override TEntity GetCached(TId id)
+ {
+ // get all from the cache -- and only the cache, then look for the entity
+ var all = Cache.GetCacheItem>(GetEntityTypeCacheKey());
+ var entity = all?.FirstOrDefault(x => _entityGetId(x).Equals(id));
+
+ // 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 (TEntity) entity?.DeepClone();
}
///
- public override bool Exists(TId id, Func repoExists)
+ public override bool Exists(TId id, Func performExits, Func> performGetAll)
{
// get all as one set, then look for the entity
- var all = GetAllCached();
+ var all = GetAllCached(performGetAll);
return all.Any(x => _entityGetId(x).Equals(id));
}
///
- public override TEntity[] GetAll(TId[] ids, Func> repoGet)
+ public override TEntity[] GetAll(TId[] ids, Func> performGetAll)
{
// get all as one set, from cache if possible, else repo
- var all = GetAllCached();
+ var all = GetAllCached(performGetAll);
// if ids have been specified, filter
if (ids.Length > 0) all = all.Where(x => ids.Contains(_entityGetId(x)));
@@ -146,16 +155,22 @@ namespace Umbraco.Core.Cache
}
// does NOT clone anything, so be nice with the returned values
- private IEnumerable GetAllCached()
+ 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 = _repoGetAll().WhereNotNull().ToArray();
- SetCacheActionToInsertEntities(entities); // may be an empty array...
+ 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 b9fe74d586..11a3cf6bb9 100644
--- a/src/Umbraco.Core/Cache/IRepositoryCachePolicy.cs
+++ b/src/Umbraco.Core/Cache/IRepositoryCachePolicy.cs
@@ -4,17 +4,28 @@ using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Cache
{
- internal interface IRepositoryCachePolicy : IDisposable
+ internal interface IRepositoryCachePolicy
where TEntity : class, IAggregateRoot
{
+ // 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 method to get the entity.
+ /// 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 repoGet);
+ TEntity Get(TId id, Func performGet, Func> performGetAll);
///
/// Gets an entity from the cache.
@@ -22,40 +33,54 @@ namespace Umbraco.Core.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 Get(TId id);
+ TEntity GetCached(TId id);
///
/// Gets a value indicating whether an entity with a specified identifier exists.
///
/// The identifier.
- /// The repository method to check for the existence of the entity.
+ /// 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 repoExists);
+ bool Exists(TId id, Func performExists, Func> performGetAll);
///
- /// Creates or updates an entity.
+ /// Creates an entity.
///
/// The entity.
- /// The repository method to create or update the entity.
- /// Creates or updates the entity in the repository, and updates the cache accordingly.
- void CreateOrUpdate(TEntity entity, Action repoCreateOrUpdate);
+ /// 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 method to remove the entity.
+ /// The repository PersistDeletedItem method.
/// Removes the entity from the repository and clears the cache.
- void Remove(TEntity entity, Action repoRemove);
+ void Delete(TEntity entity, Action persistDeleted);
///
/// Gets entities.
///
/// The identifiers.
- /// The repository method to get entities.
+ /// The repository PerformGetAll method.
/// If is empty, all entities, else the entities with the specified identifiers.
- /// fixme explain what it should do!
- TEntity[] GetAll(TId[] ids, Func> repoGet);
+ /// 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/NoCacheRepositoryCachePolicy.cs b/src/Umbraco.Core/Cache/NoCacheRepositoryCachePolicy.cs
new file mode 100644
index 0000000000..cfcee5d728
--- /dev/null
+++ b/src/Umbraco.Core/Cache/NoCacheRepositoryCachePolicy.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Umbraco.Core.Models.EntityBase;
+
+namespace Umbraco.Core.Cache
+{
+ class NoCacheRepositoryCachePolicy : IRepositoryCachePolicy
+ where TEntity : class, IAggregateRoot
+ {
+ public void ClearAll()
+ {
+ // nothing to clear - not caching
+ }
+
+ public void Create(TEntity entity, Action persistNew)
+ {
+ persistNew(entity);
+ }
+
+ public void Delete(TEntity entity, Action persistDeleted)
+ {
+ persistDeleted(entity);
+ }
+
+ public bool Exists(TId id, Func performExists, Func> performGetAll)
+ {
+ return performExists(id);
+ }
+
+ public TEntity Get(TId id, Func performGet, Func> performGetAll)
+ {
+ return performGet(id);
+ }
+
+ public TEntity[] GetAll(TId[] ids, Func> performGetAll)
+ {
+ return performGetAll(ids).ToArray();
+ }
+
+ public TEntity GetCached(TId id)
+ {
+ return null;
+ }
+
+ public void Update(TEntity entity, Action persistUpdated)
+ {
+ persistUpdated(entity);
+ }
+ }
+}
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 fcfc86cfaf..a5bfa5fcb3 100644
--- a/src/Umbraco.Core/Cache/RepositoryCachePolicyBase.cs
+++ b/src/Umbraco.Core/Cache/RepositoryCachePolicyBase.cs
@@ -9,52 +9,39 @@ namespace Umbraco.Core.Cache
///
/// The type of the entity.
/// The type of the identifier.
- internal abstract class RepositoryCachePolicyBase : DisposableObject, IRepositoryCachePolicy
+ internal abstract class RepositoryCachePolicyBase : IRepositoryCachePolicy
where TEntity : class, IAggregateRoot
{
- private Action _action;
-
protected RepositoryCachePolicyBase(IRuntimeCacheProvider cache)
{
if (cache == null) throw new ArgumentNullException(nameof(cache));
Cache = cache;
- }
+ }
protected IRuntimeCacheProvider Cache { get; }
- ///
- /// Disposing performs the actual caching action.
- ///
- protected override void DisposeResources()
- {
- _action?.Invoke();
- }
-
- ///
- /// Sets the action to execute when being disposed.
- ///
- /// An action to perform when being disposed.
- protected void SetCacheAction(Action action)
- {
- _action = action;
- }
+ ///
+ public abstract TEntity Get(TId id, Func performGet, Func> performGetAll);
///
- public abstract TEntity Get(TId id, Func repoGet);
+ public abstract TEntity GetCached(TId id);
///
- public abstract TEntity Get(TId id);
+ public abstract bool Exists(TId id, Func performExists, Func> performGetAll);
///
- public abstract bool Exists(TId id, Func repoExists);
+ public abstract void Create(TEntity entity, Action persistNew);
///
- public abstract void CreateOrUpdate(TEntity entity, Action repoCreateOrUpdate);
+ public abstract void Update(TEntity entity, Action persistUpdated);
///
- public abstract void Remove(TEntity entity, Action repoRemove);
+ public abstract void Delete(TEntity entity, Action persistDeleted);
///
- public abstract TEntity[] GetAll(TId[] ids, Func> repoGet);
+ public abstract TEntity[] GetAll(TId[] ids, Func> performGetAll);
+
+ ///
+ public abstract void ClearAll();
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Cache/SingleItemsOnlyRepositoryCachePolicy.cs b/src/Umbraco.Core/Cache/SingleItemsOnlyRepositoryCachePolicy.cs
index e734735e1a..f63ce2c023 100644
--- a/src/Umbraco.Core/Cache/SingleItemsOnlyRepositoryCachePolicy.cs
+++ b/src/Umbraco.Core/Cache/SingleItemsOnlyRepositoryCachePolicy.cs
@@ -1,3 +1,5 @@
+using System;
+using System.Collections.Generic;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Cache
@@ -19,7 +21,7 @@ namespace Umbraco.Core.Cache
: base(cache, options)
{ }
- protected override void SetCacheActionToInsertEntities(TId[] ids, TEntity[] entities)
+ protected override void InsertEntities(TId[] ids, TEntity[] entities)
{
// nop
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs
index aacd51c685..c4814a3647 100644
--- a/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs
@@ -20,6 +20,7 @@ namespace Umbraco.Core.Persistence.Repositories
internal class ContentTypeRepository : ContentTypeRepositoryBase, IContentTypeRepository
{
private readonly ITemplateRepository _templateRepository;
+ private IRepositoryCachePolicy _cachePolicy;
public ContentTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ITemplateRepository templateRepository, IMappingResolver mappingResolver)
: base(work, cache, logger, mappingResolver)
@@ -27,16 +28,15 @@ 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));
+ if (_cachePolicy != null) return _cachePolicy;
+
+ _cachePolicy = new FullDataSetRepositoryCachePolicy(RuntimeCache, GetEntityId, /*expires:*/ true);
+
+ return _cachePolicy;
}
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/DictionaryRepository.cs b/src/Umbraco.Core/Persistence/Repositories/DictionaryRepository.cs
index 00f4c3af2f..c0966ff95c 100644
--- a/src/Umbraco.Core/Persistence/Repositories/DictionaryRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/DictionaryRepository.cs
@@ -20,6 +20,7 @@ namespace Umbraco.Core.Persistence.Repositories
///
internal class DictionaryRepository : NPocoRepositoryBase, IDictionaryRepository
{
+ private IRepositoryCachePolicy _cachePolicy;
private readonly IMappingResolver _mappingResolver;
public DictionaryRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMappingResolver mappingResolver)
@@ -28,16 +29,23 @@ namespace Umbraco.Core.Persistence.Repositories
_mappingResolver = mappingResolver;
}
- private IRepositoryCachePolicyFactory _cachePolicyFactory;
- protected override IRepositoryCachePolicyFactory CachePolicyFactory => _cachePolicyFactory ??
- // custom cache policy which will not cache any results for GetAll
- (_cachePolicyFactory = new OnlySingleItemsRepositoryCachePolicyFactory(
- RuntimeCache,
- new RepositoryCachePolicyOptions
+ protected override IRepositoryCachePolicy CachePolicy
+ {
+ get
+ {
+ if (_cachePolicy != null) return _cachePolicy;
+
+ var options = new RepositoryCachePolicyOptions
{
//allow zero to be cached
GetAllCacheAllowZeroCount = true
- }));
+ };
+
+ _cachePolicy = new SingleItemsOnlyRepositoryCachePolicy(RuntimeCache, options);
+
+ return _cachePolicy;
+ }
+ }
#region Overrides of RepositoryBase
@@ -286,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, IMappingResolver mappingResolver)
@@ -325,20 +334,28 @@ namespace Umbraco.Core.Persistence.Repositories
return "cmsDictionary." + SqlSyntax.GetQuotedColumnName("id") + " in (@ids)";
}
- private IRepositoryCachePolicyFactory _cachePolicyFactory;
- protected override IRepositoryCachePolicyFactory CachePolicyFactory => _cachePolicyFactory ??
- // custom cache policy which will not cache any results for GetAll
- (_cachePolicyFactory = new OnlySingleItemsRepositoryCachePolicyFactory(
- RuntimeCache,
- new RepositoryCachePolicyOptions
+ protected override IRepositoryCachePolicy CachePolicy
+ {
+ get
+ {
+ 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, IMappingResolver mappingResolver)
@@ -378,16 +395,23 @@ namespace Umbraco.Core.Persistence.Repositories
return "cmsDictionary." + SqlSyntax.GetQuotedColumnName("key") + " in (@ids)";
}
- private IRepositoryCachePolicyFactory _cachePolicyFactory;
- protected override IRepositoryCachePolicyFactory CachePolicyFactory => _cachePolicyFactory ??
- // custom cache policy which will not cache any results for GetAll
- (_cachePolicyFactory = new OnlySingleItemsRepositoryCachePolicyFactory(
- RuntimeCache,
- new RepositoryCachePolicyOptions
+ protected override IRepositoryCachePolicy CachePolicy
+ {
+ get
+ {
+ 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 b703bab20e..2bcba58cb1 100644
--- a/src/Umbraco.Core/Persistence/Repositories/DomainRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/DomainRepository.cs
@@ -20,19 +20,22 @@ namespace Umbraco.Core.Persistence.Repositories
internal class DomainRepository : NPocoRepositoryBase, IDomainRepository
{
+ private IRepositoryCachePolicy _cachePolicy;
+
public DomainRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMappingResolver mappingResolver)
: base(work, cache, logger, mappingResolver)
{
}
- 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 a97d61eb1b..143eb92055 100644
--- a/src/Umbraco.Core/Persistence/Repositories/LanguageRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/LanguageRepository.cs
@@ -21,19 +21,22 @@ namespace Umbraco.Core.Persistence.Repositories
///
internal class LanguageRepository : NPocoRepositoryBase, ILanguageRepository
{
+ private IRepositoryCachePolicy _cachePolicy;
+
public LanguageRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMappingResolver mappingResolver)
: base(work, cache, logger, mappingResolver)
{
}
- 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 546b90e107..f79fcac57a 100644
--- a/src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs
@@ -17,20 +17,21 @@ namespace Umbraco.Core.Persistence.Repositories
///
internal class MediaTypeRepository : ContentTypeRepositoryBase, IMediaTypeRepository
{
+ private IRepositoryCachePolicy _cachePolicy;
+
public MediaTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMappingResolver mappingResolver)
: base(work, cache, logger, mappingResolver)
{ }
- 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 81cc28b05c..21f37224d1 100644
--- a/src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs
@@ -19,20 +19,21 @@ namespace Umbraco.Core.Persistence.Repositories
///
internal class MemberTypeRepository : ContentTypeRepositoryBase, IMemberTypeRepository
{
+ private IRepositoryCachePolicy _cachePolicy;
+
public MemberTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMappingResolver mappingResolver)
: base(work, cache, logger, mappingResolver)
{ }
- 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/NPocoRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/NPocoRepositoryBase.cs
index a4652c7f98..44be94df21 100644
--- a/src/Umbraco.Core/Persistence/Repositories/NPocoRepositoryBase.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/NPocoRepositoryBase.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Data.SqlServerCe;
using NPoco;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
@@ -107,7 +106,7 @@ namespace Umbraco.Core.Persistence.Repositories
protected virtual new TId GetEntityId(TEntity entity)
{
- return (TId)(object)entity.Id;
+ return (TId)(object) entity.Id;
}
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Repositories/PublicAccessRepository.cs b/src/Umbraco.Core/Persistence/Repositories/PublicAccessRepository.cs
index 4d9b68e6a9..84079ca932 100644
--- a/src/Umbraco.Core/Persistence/Repositories/PublicAccessRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/PublicAccessRepository.cs
@@ -16,19 +16,22 @@ namespace Umbraco.Core.Persistence.Repositories
{
internal class PublicAccessRepository : NPocoRepositoryBase, IPublicAccessRepository
{
+ private IRepositoryCachePolicy _cachePolicy;
+
public PublicAccessRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IMappingResolver mappingResolver)
: base(work, cache, logger, mappingResolver)
{
}
- 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/RepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs
index 33e0043f62..23ebdfbba5 100644
--- a/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs
@@ -81,25 +81,24 @@ namespace Umbraco.Core.Persistence.Repositories
///
protected override IRuntimeCacheProvider RuntimeCache => 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(() =>
- {
- //Get count of all entities of current type (TEntity) to ensure cached result is correct
- var query = Query.Where(x => x.Id != 0);
- return PerformCount(query);
- })));
+ if (_cachePolicy != null) return _cachePolicy;
+
+ var options = new RepositoryCachePolicyOptions(() =>
+ {
+ //Get count of all entities of current type (TEntity) to ensure cached result is correct
+ var query = Query.Where(x => x.Id != 0);
+ return PerformCount(query);
+ });
+
+ _cachePolicy = new DefaultRepositoryCachePolicy(RuntimeCache, options);
+
+ return _cachePolicy;
}
}
@@ -137,10 +136,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);
@@ -163,11 +159,7 @@ 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);
@@ -191,10 +183,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);
@@ -214,12 +203,7 @@ namespace Umbraco.Core.Persistence.Repositories
///
public virtual void PersistNewItem(IEntity entity)
{
- var casted = (TEntity)entity;
-
- using (var p = CachePolicyFactory.CreatePolicy())
- {
- p.CreateOrUpdate(casted, PersistNewItem);
- }
+ CachePolicy.Create((TEntity) entity, PersistNewItem);
}
///
@@ -228,12 +212,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);
}
///
@@ -242,12 +221,7 @@ 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);
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs b/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs
index 329b53d042..18a58dcac2 100644
--- a/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs
@@ -35,6 +35,7 @@ namespace Umbraco.Core.Persistence.Repositories
private readonly ITemplatesSection _templateConfig;
private readonly ViewHelper _viewHelper;
private readonly MasterPageHelper _masterPageHelper;
+ private IRepositoryCachePolicy _cachePolicy;
public TemplateRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, IFileSystem masterpageFileSystem, IFileSystem viewFileSystem, ITemplatesSection templateConfig, IMappingResolver mappingResolver)
: base(work, cache, logger, mappingResolver)
@@ -46,15 +47,15 @@ namespace Umbraco.Core.Persistence.Repositories
_masterPageHelper = new MasterPageHelper(_masterpagesFileSystem);
}
-
- 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 603eb0a3ce..393b909b06 100644
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -74,9 +74,7 @@
-
-
@@ -84,8 +82,8 @@
-
+
@@ -94,7 +92,6 @@
-
diff --git a/src/Umbraco.Tests/Cache/DefaultCachePolicyTests.cs b/src/Umbraco.Tests/Cache/DefaultCachePolicyTests.cs
index 9b0aaac78b..be523ffad1 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[] {}, o => new[]
- {
- new AuditItem(1, "blah", AuditType.Copy, 123),
- new AuditItem(2, "blah2", AuditType.Copy, 123)
- });
- }
+
+ var found = defaultPolicy.GetAll(new object[] {}, ids => new[]
+ {
+ 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..355b054c1d 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..12f4c954a2 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[] { }, o => new[]
- {
- new AuditItem(1, "blah", AuditType.Copy, 123),
- new AuditItem(2, "blah2", AuditType.Copy, 123)
- });
- }
+
+ var found = defaultPolicy.GetAll(new object[] { }, ids => new[]
+ {
+ 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);
}
}