UnitOfWork RIP, troubleshoot and fix, tests
This commit is contained in:
@@ -28,9 +28,9 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
protected override bool IsPublishing => ContentType.IsPublishingConst;
|
||||
|
||||
protected override IRepositoryCachePolicy<IContentType, int> CreateCachePolicy(IRuntimeCacheProvider runtimeCache)
|
||||
protected override IRepositoryCachePolicy<IContentType, int> CreateCachePolicy()
|
||||
{
|
||||
return new FullDataSetRepositoryCachePolicy<IContentType, int>(runtimeCache, GetEntityId, /*expires:*/ true);
|
||||
return new FullDataSetRepositoryCachePolicy<IContentType, int>(GlobalIsolatedCache, ScopeAccessor, GetEntityId, /*expires:*/ true);
|
||||
}
|
||||
|
||||
protected override IContentType PerformGet(int id)
|
||||
@@ -201,9 +201,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
var children = Get(query);
|
||||
foreach (var child in children)
|
||||
{
|
||||
//NOTE: We must cast here so that it goes to the outter method to
|
||||
// ensure the cache is updated.
|
||||
PersistDeletedItem((IEntity)child);
|
||||
PersistDeletedItem(child);
|
||||
}
|
||||
|
||||
//Before we call the base class methods to run all delete clauses, we need to first
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
: base(scopeAccessor, cache, logger)
|
||||
{ }
|
||||
|
||||
protected override IRepositoryCachePolicy<IDictionaryItem, int> CreateCachePolicy(IRuntimeCacheProvider runtimeCache)
|
||||
protected override IRepositoryCachePolicy<IDictionaryItem, int> CreateCachePolicy()
|
||||
{
|
||||
var options = new RepositoryCachePolicyOptions
|
||||
{
|
||||
@@ -30,7 +30,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
GetAllCacheAllowZeroCount = true
|
||||
};
|
||||
|
||||
return new SingleItemsOnlyRepositoryCachePolicy<IDictionaryItem, int>(runtimeCache, options);
|
||||
return new SingleItemsOnlyRepositoryCachePolicy<IDictionaryItem, int>(GlobalIsolatedCache, ScopeAccessor, options);
|
||||
}
|
||||
|
||||
#region Overrides of RepositoryBase<int,DictionaryItem>
|
||||
@@ -333,7 +333,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
return "cmsDictionary." + SqlSyntax.GetQuotedColumnName("id") + " in (@ids)";
|
||||
}
|
||||
|
||||
protected override IRepositoryCachePolicy<IDictionaryItem, Guid> CreateCachePolicy(IRuntimeCacheProvider runtimeCache)
|
||||
protected override IRepositoryCachePolicy<IDictionaryItem, Guid> CreateCachePolicy()
|
||||
{
|
||||
var options = new RepositoryCachePolicyOptions
|
||||
{
|
||||
@@ -341,7 +341,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
GetAllCacheAllowZeroCount = true
|
||||
};
|
||||
|
||||
return new SingleItemsOnlyRepositoryCachePolicy<IDictionaryItem, Guid>(runtimeCache, options);
|
||||
return new SingleItemsOnlyRepositoryCachePolicy<IDictionaryItem, Guid>(GlobalIsolatedCache, ScopeAccessor, options);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,7 +386,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
return "cmsDictionary." + SqlSyntax.GetQuotedColumnName("key") + " in (@ids)";
|
||||
}
|
||||
|
||||
protected override IRepositoryCachePolicy<IDictionaryItem, string> CreateCachePolicy(IRuntimeCacheProvider runtimeCache)
|
||||
protected override IRepositoryCachePolicy<IDictionaryItem, string> CreateCachePolicy()
|
||||
{
|
||||
var options = new RepositoryCachePolicyOptions
|
||||
{
|
||||
@@ -394,7 +394,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
GetAllCacheAllowZeroCount = true
|
||||
};
|
||||
|
||||
return new SingleItemsOnlyRepositoryCachePolicy<IDictionaryItem, string>(runtimeCache, options);
|
||||
return new SingleItemsOnlyRepositoryCachePolicy<IDictionaryItem, string>(GlobalIsolatedCache, ScopeAccessor, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Exceptions;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
|
||||
@@ -20,9 +20,9 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
: base(scopeAccessor, cache, logger)
|
||||
{ }
|
||||
|
||||
protected override IRepositoryCachePolicy<IDomain, int> CreateCachePolicy(IRuntimeCacheProvider runtimeCache)
|
||||
protected override IRepositoryCachePolicy<IDomain, int> CreateCachePolicy()
|
||||
{
|
||||
return new FullDataSetRepositoryCachePolicy<IDomain, int>(runtimeCache, GetEntityId, /*expires:*/ false);
|
||||
return new FullDataSetRepositoryCachePolicy<IDomain, int>(GlobalIsolatedCache, ScopeAccessor, GetEntityId, /*expires:*/ false);
|
||||
}
|
||||
|
||||
protected override IDomain PerformGet(int id)
|
||||
|
||||
@@ -6,6 +6,7 @@ using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Exceptions;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Scoping;
|
||||
@@ -29,10 +30,9 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
}
|
||||
|
||||
// never cache
|
||||
private static readonly IRuntimeCacheProvider NullCache = new NullCacheProvider();
|
||||
protected override IRuntimeCacheProvider GetIsolatedCache(IsolatedRuntimeCache provider)
|
||||
protected override IRepositoryCachePolicy<EntityContainer, int> CreateCachePolicy()
|
||||
{
|
||||
return NullCache;
|
||||
return NoCacheRepositoryCachePolicy<EntityContainer, int>.Instance;
|
||||
}
|
||||
|
||||
protected override EntityContainer PerformGet(int id)
|
||||
|
||||
@@ -22,9 +22,9 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
: base(scopeAccessor, cache, logger)
|
||||
{ }
|
||||
|
||||
protected override IRepositoryCachePolicy<ILanguage, int> CreateCachePolicy(IRuntimeCacheProvider runtimeCache)
|
||||
protected override IRepositoryCachePolicy<ILanguage, int> CreateCachePolicy()
|
||||
{
|
||||
return new FullDataSetRepositoryCachePolicy<ILanguage, int>(runtimeCache, GetEntityId, /*expires:*/ false);
|
||||
return new FullDataSetRepositoryCachePolicy<ILanguage, int>(GlobalIsolatedCache, ScopeAccessor, GetEntityId, /*expires:*/ false);
|
||||
}
|
||||
|
||||
#region Overrides of RepositoryBase<int,Language>
|
||||
|
||||
@@ -8,6 +8,7 @@ using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Exceptions;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Umbraco.Core.Persistence.Factories;
|
||||
|
||||
@@ -22,9 +22,9 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
protected override bool IsPublishing => MediaType.IsPublishingConst;
|
||||
|
||||
protected override IRepositoryCachePolicy<IMediaType, int> CreateCachePolicy(IRuntimeCacheProvider runtimeCache)
|
||||
protected override IRepositoryCachePolicy<IMediaType, int> CreateCachePolicy()
|
||||
{
|
||||
return new FullDataSetRepositoryCachePolicy<IMediaType, int>(runtimeCache, GetEntityId, /*expires:*/ true);
|
||||
return new FullDataSetRepositoryCachePolicy<IMediaType, int>(GlobalIsolatedCache, ScopeAccessor, GetEntityId, /*expires:*/ true);
|
||||
}
|
||||
|
||||
protected override IMediaType PerformGet(int id)
|
||||
|
||||
@@ -6,6 +6,7 @@ using NPoco;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Umbraco.Core.Persistence.Factories;
|
||||
|
||||
@@ -23,9 +23,9 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
protected override bool IsPublishing => MemberType.IsPublishingConst;
|
||||
|
||||
protected override IRepositoryCachePolicy<IMemberType, int> CreateCachePolicy(IRuntimeCacheProvider runtimeCache)
|
||||
protected override IRepositoryCachePolicy<IMemberType, int> CreateCachePolicy()
|
||||
{
|
||||
return new FullDataSetRepositoryCachePolicy<IMemberType, int>(runtimeCache, GetEntityId, /*expires:*/ true);
|
||||
return new FullDataSetRepositoryCachePolicy<IMemberType, int>(GlobalIsolatedCache, ScopeAccessor, GetEntityId, /*expires:*/ true);
|
||||
}
|
||||
|
||||
protected override IMemberType PerformGet(int id)
|
||||
|
||||
@@ -18,9 +18,9 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
: base(scopeAccessor, cache, logger)
|
||||
{ }
|
||||
|
||||
protected override IRepositoryCachePolicy<PublicAccessEntry, Guid> CreateCachePolicy(IRuntimeCacheProvider runtimeCache)
|
||||
protected override IRepositoryCachePolicy<PublicAccessEntry, Guid> CreateCachePolicy()
|
||||
{
|
||||
return new FullDataSetRepositoryCachePolicy<PublicAccessEntry, Guid>(runtimeCache, GetEntityId, /*expires:*/ false);
|
||||
return new FullDataSetRepositoryCachePolicy<PublicAccessEntry, Guid>(GlobalIsolatedCache, ScopeAccessor, GetEntityId, /*expires:*/ false);
|
||||
}
|
||||
|
||||
protected override PublicAccessEntry PerformGet(Guid id)
|
||||
|
||||
@@ -22,9 +22,9 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
: base(scopeAccessor, cache, logger)
|
||||
{ }
|
||||
|
||||
protected override IRepositoryCachePolicy<IRelationType, int> CreateCachePolicy(IRuntimeCacheProvider runtimeCache)
|
||||
protected override IRepositoryCachePolicy<IRelationType, int> CreateCachePolicy()
|
||||
{
|
||||
return new FullDataSetRepositoryCachePolicy<IRelationType, int>(runtimeCache, GetEntityId, /*expires:*/ true);
|
||||
return new FullDataSetRepositoryCachePolicy<IRelationType, int>(GlobalIsolatedCache, ScopeAccessor, GetEntityId, /*expires:*/ true);
|
||||
}
|
||||
|
||||
#region Overrides of RepositoryBase<int,RelationType>
|
||||
|
||||
@@ -18,7 +18,6 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
where TEntity : class, IAggregateRoot
|
||||
{
|
||||
private IRepositoryCachePolicy<TEntity, TId> _cachePolicy;
|
||||
private IRuntimeCacheProvider _isolatedCache;
|
||||
|
||||
protected RepositoryBase(IScopeAccessor scopeAccessor, CacheHelper cache, ILogger logger)
|
||||
{
|
||||
@@ -31,6 +30,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
protected CacheHelper GlobalCache { get; }
|
||||
|
||||
protected IRuntimeCacheProvider GlobalIsolatedCache => GlobalCache.IsolatedRuntimeCache.GetOrCreateCache<TEntity>();
|
||||
|
||||
protected IScopeAccessor ScopeAccessor { get; }
|
||||
|
||||
protected IScope AmbientScope
|
||||
@@ -56,38 +57,28 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The runtime cache used for this repo by default is the isolated cache for this type
|
||||
/// Gets the isolated cache.
|
||||
/// </summary>
|
||||
/// <remarks>Depends on the ambient scope cache mode.</remarks>
|
||||
protected IRuntimeCacheProvider IsolatedCache
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_isolatedCache != null) return _isolatedCache;
|
||||
|
||||
IsolatedRuntimeCache provider;
|
||||
switch (AmbientScope.RepositoryCacheMode)
|
||||
{
|
||||
case RepositoryCacheMode.Default:
|
||||
provider = GlobalCache.IsolatedRuntimeCache;
|
||||
break;
|
||||
return GlobalCache.IsolatedRuntimeCache.GetOrCreateCache<TEntity>();
|
||||
case RepositoryCacheMode.Scoped:
|
||||
provider = AmbientScope.IsolatedRuntimeCache;
|
||||
break;
|
||||
return AmbientScope.IsolatedRuntimeCache.GetOrCreateCache<TEntity>();
|
||||
case RepositoryCacheMode.None:
|
||||
return new NullCacheProvider(); // fixme cache instance
|
||||
return NullCacheProvider.Instance;
|
||||
default:
|
||||
throw new Exception("oops: cache mode.");
|
||||
}
|
||||
|
||||
return _isolatedCache = GetIsolatedCache(provider);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual IRuntimeCacheProvider GetIsolatedCache(IsolatedRuntimeCache provider)
|
||||
{
|
||||
return provider.GetOrCreateCache<TEntity>();
|
||||
}
|
||||
|
||||
// fixme - but now that we have 1 unique repository?
|
||||
// this is a *bad* idea because PerformCount captures the current repository and its UOW
|
||||
//
|
||||
//private static RepositoryCachePolicyOptions _defaultOptions;
|
||||
@@ -132,39 +123,35 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
// }
|
||||
//}
|
||||
|
||||
protected virtual IRepositoryCachePolicy<TEntity, TId> CachePolicy
|
||||
protected IRepositoryCachePolicy<TEntity, TId> CachePolicy
|
||||
{
|
||||
get
|
||||
{
|
||||
if (GlobalCache == CacheHelper.NoCache)
|
||||
return _cachePolicy = NoCacheRepositoryCachePolicy<TEntity, TId>.Instance;
|
||||
return NoCacheRepositoryCachePolicy<TEntity, TId>.Instance;
|
||||
|
||||
// create the cache policy using IsolatedCache which is either global
|
||||
// or scoped depending on the repository cache mode for the current scope
|
||||
|
||||
switch (AmbientScope.RepositoryCacheMode)
|
||||
{
|
||||
case RepositoryCacheMode.Default:
|
||||
_cachePolicy = CreateCachePolicy(IsolatedCache);
|
||||
break;
|
||||
case RepositoryCacheMode.Scoped:
|
||||
_cachePolicy = CreateCachePolicy(IsolatedCache);
|
||||
var globalIsolatedCache = GetIsolatedCache(GlobalCache.IsolatedRuntimeCache);
|
||||
_cachePolicy = _cachePolicy.Scoped(globalIsolatedCache, AmbientScope);
|
||||
break;
|
||||
// return the same cache policy in both cases - the cache policy is
|
||||
// supposed to pick either the global or scope cache depending on the
|
||||
// scope cache mode
|
||||
return _cachePolicy ?? (_cachePolicy = CreateCachePolicy());
|
||||
case RepositoryCacheMode.None:
|
||||
_cachePolicy = NoCacheRepositoryCachePolicy<TEntity, TId>.Instance;
|
||||
break;
|
||||
return NoCacheRepositoryCachePolicy<TEntity, TId>.Instance;
|
||||
default:
|
||||
throw new Exception("oops: cache mode.");
|
||||
}
|
||||
|
||||
return _cachePolicy;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual IRepositoryCachePolicy<TEntity, TId> CreateCachePolicy(IRuntimeCacheProvider runtimeCache)
|
||||
protected virtual IRepositoryCachePolicy<TEntity, TId> CreateCachePolicy()
|
||||
{
|
||||
return new DefaultRepositoryCachePolicy<TEntity, TId>(runtimeCache, DefaultOptions);
|
||||
return new DefaultRepositoryCachePolicy<TEntity, TId>(GlobalIsolatedCache, ScopeAccessor, DefaultOptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -175,9 +162,9 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
public void Save(TEntity entity)
|
||||
{
|
||||
if (entity.HasIdentity == false)
|
||||
PersistNewItem(entity);
|
||||
CachePolicy.Create(entity, PersistNewItem);
|
||||
else
|
||||
PersistUpdatedItem(entity);
|
||||
CachePolicy.Update(entity, PersistUpdatedItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -186,7 +173,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
/// <param name="entity"></param>
|
||||
public virtual void Delete(TEntity entity)
|
||||
{
|
||||
PersistDeletedItem(entity);
|
||||
CachePolicy.Delete(entity, PersistDeletedItem);
|
||||
}
|
||||
|
||||
protected abstract TEntity PerformGet(TId id);
|
||||
@@ -194,6 +181,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
protected abstract IEnumerable<TEntity> PerformGetByQuery(IQuery<TEntity> query);
|
||||
protected abstract bool PerformExists(TId id);
|
||||
protected abstract int PerformCount(IQuery<TEntity> query);
|
||||
|
||||
protected abstract void PersistNewItem(TEntity item);
|
||||
protected abstract void PersistUpdatedItem(TEntity item);
|
||||
protected abstract void PersistDeletedItem(TEntity item);
|
||||
@@ -262,32 +250,5 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
{
|
||||
return PerformCount(query);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unit of work method that tells the repository to persist the new entity
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
public virtual void PersistNewItem(IEntity entity)
|
||||
{
|
||||
CachePolicy.Create((TEntity) entity, PersistNewItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unit of work method that tells the repository to persist the updated entity
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
public virtual void PersistUpdatedItem(IEntity entity)
|
||||
{
|
||||
CachePolicy.Update((TEntity) entity, PersistUpdatedItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unit of work method that tells the repository to persist the deletion of the entity
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
public virtual void PersistDeletedItem(IEntity entity)
|
||||
{
|
||||
CachePolicy.Delete((TEntity) entity, PersistDeletedItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
: base(scopeAccessor, CacheHelper.CreateDisabledCacheHelper(), logger)
|
||||
{ }
|
||||
|
||||
protected override IRepositoryCachePolicy<IServerRegistration, int> CreateCachePolicy(IRuntimeCacheProvider runtimeCache)
|
||||
protected override IRepositoryCachePolicy<IServerRegistration, int> CreateCachePolicy()
|
||||
{
|
||||
// fixme - wtf are we doing with cache here?
|
||||
// why are we using disabled cache helper up there?
|
||||
@@ -29,7 +29,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
// and this is because the repository is special and should not participate in scopes
|
||||
// (cleanup in v8)
|
||||
//
|
||||
return new FullDataSetRepositoryCachePolicy<IServerRegistration, int>(GlobalCache.RuntimeCache, GetEntityId, /*expires:*/ false);
|
||||
return new FullDataSetRepositoryCachePolicy<IServerRegistration, int>(GlobalCache.RuntimeCache, ScopeAccessor, GetEntityId, /*expires:*/ false);
|
||||
}
|
||||
|
||||
public void ClearCache()
|
||||
|
||||
@@ -42,9 +42,9 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
_masterPageHelper = new MasterPageHelper(_masterpagesFileSystem);
|
||||
}
|
||||
|
||||
protected override IRepositoryCachePolicy<ITemplate, int> CreateCachePolicy(IRuntimeCacheProvider runtimeCache)
|
||||
protected override IRepositoryCachePolicy<ITemplate, int> CreateCachePolicy()
|
||||
{
|
||||
return new FullDataSetRepositoryCachePolicy<ITemplate, int>(runtimeCache, GetEntityId, /*expires:*/ false);
|
||||
return new FullDataSetRepositoryCachePolicy<ITemplate, int>(GlobalIsolatedCache, ScopeAccessor, GetEntityId, /*expires:*/ false);
|
||||
}
|
||||
|
||||
#region Overrides of RepositoryBase<int,ITemplate>
|
||||
|
||||
@@ -60,6 +60,10 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
if (_passwordConfigInitialized)
|
||||
return _passwordConfigJson;
|
||||
|
||||
// fixme - this is bad
|
||||
// because the membership provider we're trying to get has a dependency on the user service
|
||||
// and we should not depend on services in repositories - need a way better way to do this
|
||||
|
||||
var userMembershipProvider = MembershipProviderExtensions.GetUsersMembershipProvider();
|
||||
var passwordConfig = userMembershipProvider == null || userMembershipProvider.PasswordFormat != MembershipPasswordFormat.Hashed
|
||||
? null
|
||||
|
||||
Reference in New Issue
Block a user