diff --git a/src/Umbraco.Core/Cache/DefaultRepositoryCachePolicy.cs b/src/Umbraco.Core/Cache/DefaultRepositoryCachePolicy.cs
index 66d9b2ac25..45e79a1b67 100644
--- a/src/Umbraco.Core/Cache/DefaultRepositoryCachePolicy.cs
+++ b/src/Umbraco.Core/Cache/DefaultRepositoryCachePolicy.cs
@@ -11,6 +11,10 @@ namespace Umbraco.Core.Cache
///
///
///
+ ///
+ /// This cache policy uses sliding expiration and caches instances for 5 minutes. However if allow zero count is true, then we use the
+ /// default policy with no expiry.
+ ///
internal class DefaultRepositoryCachePolicy : DisposableObject, IRepositoryCachePolicy
where TEntity : class, IAggregateRoot
{
@@ -54,7 +58,9 @@ namespace Umbraco.Core.Cache
//just to be safe, we cannot cache an item without an identity
if (entity.HasIdentity)
{
- Cache.InsertCacheItem(GetCacheIdKey(entity.Id), () => entity);
+ Cache.InsertCacheItem(GetCacheIdKey(entity.Id), () => entity,
+ timeout: TimeSpan.FromMinutes(5),
+ isSliding: true);
}
//If there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
@@ -225,7 +231,9 @@ namespace Umbraco.Core.Cache
//just to be safe, we cannot cache an item without an identity
if (entity.HasIdentity)
{
- Cache.InsertCacheItem(cacheKey, () => entity);
+ Cache.InsertCacheItem(cacheKey, () => entity,
+ timeout: TimeSpan.FromMinutes(5),
+ isSliding: true);
}
});
}
@@ -244,6 +252,7 @@ namespace Umbraco.Core.Cache
{
//there was nothing returned but we want to cache a zero count result so add an TEntity[] to the cache
// to signify that there is a zero count cache
+ //NOTE: Don't set expiry/sliding for a zero count
Cache.InsertCacheItem(GetCacheTypeKey(), () => new TEntity[] {});
}
else
@@ -256,7 +265,9 @@ namespace Umbraco.Core.Cache
//just to be safe, we cannot cache an item without an identity
if (localCopy.HasIdentity)
{
- Cache.InsertCacheItem(GetCacheIdKey(entity.Id), () => localCopy);
+ Cache.InsertCacheItem(GetCacheIdKey(entity.Id), () => localCopy,
+ timeout: TimeSpan.FromMinutes(5),
+ isSliding: true);
}
}
}
diff --git a/src/Umbraco.Core/Cache/FullDataSetRepositoryCachePolicy.cs b/src/Umbraco.Core/Cache/FullDataSetRepositoryCachePolicy.cs
index 40b100ef67..3b3c98fc80 100644
--- a/src/Umbraco.Core/Cache/FullDataSetRepositoryCachePolicy.cs
+++ b/src/Umbraco.Core/Cache/FullDataSetRepositoryCachePolicy.cs
@@ -11,6 +11,10 @@ namespace Umbraco.Core.Cache
///
///
///
+ ///
+ /// This caching policy has no sliding expiration but uses the default ObjectCache.InfiniteAbsoluteExpiration as it's timeout, so it
+ /// should not leave the cache unless the cache memory is exceeded and it gets thrown out.
+ ///
internal class FullDataSetRepositoryCachePolicy : DefaultRepositoryCachePolicy
where TEntity : class, IAggregateRoot
{
diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentType.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedContentType.cs
index 5f30c08ce7..3cff4f0298 100644
--- a/src/Umbraco.Core/Models/PublishedContent/PublishedContentType.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/PublishedContentType.cs
@@ -98,45 +98,10 @@ namespace Umbraco.Core.Models.PublishedContent
#endregion
- #region Cache
-
- // these methods are called by ContentTypeCacheRefresher and DataTypeCacheRefresher
-
- internal static void ClearAll()
- {
- Logging.LogHelper.Debug("Clear all.");
- // ok and faster to do it by types, assuming noone else caches PublishedContentType instances
- //ApplicationContext.Current.ApplicationCache.ClearStaticCacheByKeySearch("PublishedContentType_");
- ApplicationContext.Current.ApplicationCache.StaticCache.ClearCacheObjectTypes();
- }
-
- internal static void ClearContentType(int id)
- {
- Logging.LogHelper.Debug("Clear content type w/id {0}.", () => id);
- // requires a predicate because the key does not contain the ID
- // faster than key strings comparisons anyway
- ApplicationContext.Current.ApplicationCache.StaticCache.ClearCacheObjectTypes(
- (key, value) => value.Id == id);
- }
-
- internal static void ClearDataType(int id)
- {
- Logging.LogHelper.Debug("Clear data type w/id {0}.", () => id);
- // there is no recursion to handle here because a PublishedContentType contains *all* its
- // properties ie both its own properties and those that were inherited (it's based upon an
- // IContentTypeComposition) and so every PublishedContentType having a property based upon
- // the cleared data type, be it local or inherited, will be cleared.
- ApplicationContext.Current.ApplicationCache.StaticCache.ClearCacheObjectTypes(
- (key, value) => value.PropertyTypes.Any(x => x.DataTypeId == id));
- }
-
+
public static PublishedContentType Get(PublishedItemType itemType, string alias)
{
- var key = string.Format("PublishedContentType_{0}_{1}",
- itemType.ToString().ToLowerInvariant(), alias.ToLowerInvariant());
-
- var type = ApplicationContext.Current.ApplicationCache.StaticCache.GetCacheItem(key,
- () => CreatePublishedContentType(itemType, alias));
+ var type = CreatePublishedContentType(itemType, alias);
return type;
}
@@ -169,21 +134,8 @@ namespace Umbraco.Core.Models.PublishedContent
return new PublishedContentType(contentType);
}
- // for unit tests - changing the callback must reset the cache obviously
- private static Func _getPublishedContentTypeCallBack;
- internal static Func GetPublishedContentTypeCallback
- {
- get { return _getPublishedContentTypeCallBack; }
- set
- {
- // see note above
- //ClearAll();
- ApplicationContext.Current.ApplicationCache.StaticCache.ClearCacheByKeySearch("PublishedContentType_");
-
- _getPublishedContentTypeCallBack = value;
- }
- }
-
- #endregion
+ // for unit tests
+ internal static Func GetPublishedContentTypeCallback { get; set; }
+
}
}
diff --git a/src/Umbraco.Core/Persistence/Relators/UserSectionRelator.cs b/src/Umbraco.Core/Persistence/Relators/UserSectionRelator.cs
index 859fa7cf5a..923348e729 100644
--- a/src/Umbraco.Core/Persistence/Relators/UserSectionRelator.cs
+++ b/src/Umbraco.Core/Persistence/Relators/UserSectionRelator.cs
@@ -18,8 +18,11 @@ namespace Umbraco.Core.Persistence.Relators
// Is this the same DictionaryItem as the current one we're processing
if (Current != null && Current.Id == a.Id)
{
- // Yes, just add this User2AppDto to the current item's collection
- Current.User2AppDtos.Add(p);
+ if (p.AppAlias.IsNullOrWhiteSpace() == false)
+ {
+ // Yes, just add this User2AppDto to the current item's collection
+ Current.User2AppDtos.Add(p);
+ }
// Return null to indicate we're not done with this User yet
return null;
@@ -35,7 +38,7 @@ namespace Umbraco.Core.Persistence.Relators
Current = a;
Current.User2AppDtos = new List();
//this can be null since we are doing a left join
- if (p.AppAlias != null)
+ if (p.AppAlias.IsNullOrWhiteSpace() == false)
{
Current.User2AppDtos.Add(p);
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs
index cc3fb37aa6..1f5cc1ecd4 100644
--- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs
@@ -156,7 +156,7 @@ namespace Umbraco.Core.Persistence.Repositories
"DELETE FROM cmsContentXml WHERE nodeId = @Id",
"DELETE FROM cmsContent WHERE nodeId = @Id",
"DELETE FROM umbracoAccess WHERE nodeId = @Id",
- "DELETE FROM umbracoNode WHERE id = @Id"
+ "DELETE FROM umbracoNode WHERE id = @Id"
};
return list;
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs
index fd061dbda9..eb8dfde6b0 100644
--- a/src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs
@@ -85,7 +85,6 @@ namespace Umbraco.Core.Persistence.Repositories
return moveInfo;
}
-
///
/// Returns the content type ids that match the query
///
diff --git a/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs b/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs
index 955e316bc3..acc17b370a 100644
--- a/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs
@@ -475,7 +475,7 @@ namespace Umbraco.Core.Persistence.Repositories
if (aliases.Any() == false) return base.GetAll();
//return from base.GetAll, this is all cached
- return base.GetAll().Where(x => aliases.Contains(x.Alias));
+ return base.GetAll().Where(x => aliases.InvariantContains(x.Alias));
}
public IEnumerable GetChildren(int masterTemplateId)
diff --git a/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs b/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs
index 44a6efe9ff..c44b3f2b51 100644
--- a/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs
+++ b/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs
@@ -141,9 +141,7 @@ namespace Umbraco.Web.Cache
ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheByKeySearch(CacheKeys.ContentTypeCacheKey);
//clear static object cache
global::umbraco.cms.businesslogic.ContentType.RemoveAllDataTypeCache();
-
- PublishedContentType.ClearAll();
-
+
base.RefreshAll();
}
@@ -280,9 +278,7 @@ namespace Umbraco.Web.Cache
//clears the dictionary object cache of the legacy ContentType
global::umbraco.cms.businesslogic.ContentType.RemoveFromDataTypeCache(payload.Alias);
-
- PublishedContentType.ClearContentType(payload.Id);
-
+
//need to recursively clear the cache for each child content type
foreach (var descendant in payload.DescendantPayloads)
{
diff --git a/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs b/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs
index 11b3ab6294..173f4dcb86 100644
--- a/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs
+++ b/src/Umbraco.Web/Cache/DataTypeCacheRefresher.cs
@@ -108,7 +108,6 @@ namespace Umbraco.Web.Cache
if (dataTypeCache)
dataTypeCache.Result.ClearCacheByKeySearch(string.Format("{0}{1}", CacheKeys.DataTypePreValuesCacheKey, payload.Id));
- PublishedContentType.ClearDataType(payload.Id);
});
base.Refresh(jsonPayload);
diff --git a/src/Umbraco.Web/Install/InstallSteps/SetUmbracoVersionStep.cs b/src/Umbraco.Web/Install/InstallSteps/SetUmbracoVersionStep.cs
index 6523925505..f7c9b3d6a5 100644
--- a/src/Umbraco.Web/Install/InstallSteps/SetUmbracoVersionStep.cs
+++ b/src/Umbraco.Web/Install/InstallSteps/SetUmbracoVersionStep.cs
@@ -40,9 +40,14 @@ namespace Umbraco.Web.Install.InstallSteps
var clientDependencyConfig = new ClientDependencyConfiguration(_applicationContext.ProfilingLogger.Logger);
var clientDependencyUpdated = clientDependencyConfig.IncreaseVersionNumber();
- var security = new WebSecurity(_httpContext, _applicationContext);
- security.PerformLogin(0);
-
+ //During a new install we'll log the default user in (which is id = 0).
+ // During an upgrade, the user will already need to be logged in in order to run the installer.
+ if (InstallTypeTarget == InstallationType.NewInstall)
+ {
+ var security = new WebSecurity(_httpContext, _applicationContext);
+ security.PerformLogin(0);
+ }
+
//reports the ended install
var ih = new InstallHelper(UmbracoContext.Current);
ih.InstallStatus(true, "");
diff --git a/src/Umbraco.Web/UmbracoContext.cs b/src/Umbraco.Web/UmbracoContext.cs
index 3c2b7267a6..fca5ff2371 100644
--- a/src/Umbraco.Web/UmbracoContext.cs
+++ b/src/Umbraco.Web/UmbracoContext.cs
@@ -125,6 +125,7 @@ namespace Umbraco.Web
if (umbracoSettings == null) throw new ArgumentNullException("umbracoSettings");
if (urlProviders == null) throw new ArgumentNullException("urlProviders");
+ //if there's already a singleton, and we're not replacing then there's no need to ensure anything
if (UmbracoContext.Current != null)
{
if (replaceContext == false)
@@ -132,6 +133,39 @@ namespace Umbraco.Web
UmbracoContext.Current._replacing = true;
}
+ var umbracoContext = CreateContext(httpContext, applicationContext, webSecurity, umbracoSettings, urlProviders, preview ?? false);
+
+ //assign the singleton
+ UmbracoContext.Current = umbracoContext;
+ return UmbracoContext.Current;
+ }
+
+ ///
+ /// Creates a standalone UmbracoContext instance
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// A new instance of UmbracoContext
+ ///
+ public static UmbracoContext CreateContext(
+ HttpContextBase httpContext,
+ ApplicationContext applicationContext,
+ WebSecurity webSecurity,
+ IUmbracoSettingsSection umbracoSettings,
+ IEnumerable urlProviders,
+ bool preview)
+ {
+ if (httpContext == null) throw new ArgumentNullException("httpContext");
+ if (applicationContext == null) throw new ArgumentNullException("applicationContext");
+ if (webSecurity == null) throw new ArgumentNullException("webSecurity");
+ if (umbracoSettings == null) throw new ArgumentNullException("umbracoSettings");
+ if (urlProviders == null) throw new ArgumentNullException("urlProviders");
+
var umbracoContext = new UmbracoContext(
httpContext,
applicationContext,
@@ -142,15 +176,15 @@ namespace Umbraco.Web
// create the RoutingContext, and assign
var routingContext = new RoutingContext(
umbracoContext,
-
+
//TODO: Until the new cache is done we can't really expose these to override/mock
new Lazy>(() => ContentFinderResolver.Current.Finders),
new Lazy(() => ContentLastChanceFinderResolver.Current.Finder),
-
+
// create the nice urls provider
// there's one per request because there are some behavior parameters that can be changed
new Lazy(
- () => new UrlProvider(
+ () => new UrlProvider(
umbracoContext,
umbracoSettings.WebRouting,
urlProviders),
@@ -159,9 +193,7 @@ namespace Umbraco.Web
//assign the routing context back
umbracoContext.RoutingContext = routingContext;
- //assign the singleton
- UmbracoContext.Current = umbracoContext;
- return UmbracoContext.Current;
+ return umbracoContext;
}
///
@@ -460,17 +492,9 @@ namespace Umbraco.Web
protected override void DisposeResources()
{
Security.DisposeIfDisposable();
- Security = null;
- _umbracoContext = null;
- //Before we set these to null but in fact these are application lifespan singletons so
- //there's no reason we need to set them to null and this also caused a problem with packages
- //trying to access the cache properties on RequestEnd.
- //http://issues.umbraco.org/issue/U4-2734
- //http://our.umbraco.org/projects/developer-tools/301-url-tracker/version-2/44327-Issues-with-URL-Tracker-in-614
- //ContentCache = null;
- //MediaCache = null;
- //Application = null;
+ //If not running in a web ctx, ensure the thread based instance is nulled
+ _umbracoContext = null;
}
}
}
\ No newline at end of file