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); } }