diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/TreeDefinitionCollection.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/TreeDefinitionCollection.cs index f1c5d4004b..4b43065538 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/TreeDefinitionCollection.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/TreeDefinitionCollection.cs @@ -27,8 +27,9 @@ namespace umbraco.cms.presentation.Trees //create singleton private static readonly TreeDefinitionCollection instance = new TreeDefinitionCollection(); - private static readonly ReaderWriterLockSlim Lock = new ReaderWriterLockSlim(); - + private static readonly object Locker = new object(); + private static volatile bool _ensureTrees = false; + public static TreeDefinitionCollection Instance { get @@ -127,7 +128,12 @@ namespace umbraco.cms.presentation.Trees public void ReRegisterTrees() { - EnsureTreesRegistered(true); + //clears the trees/flag so that they are lazily refreshed on next access + lock (Locker) + { + this.Clear(); + _ensureTrees = false; + } } /// @@ -136,70 +142,68 @@ namespace umbraco.cms.presentation.Trees /// This will also store an instance of each tree object in the TreeDefinition class which should be /// used when referencing all tree classes. /// - private void EnsureTreesRegistered(bool clearFirst = false) + private void EnsureTreesRegistered() { - using (var l = new UpgradeableReadLock(Lock)) - { - if (clearFirst) - { - this.Clear(); - } + if (_ensureTrees == false) + { + lock (Locker) + { + if (_ensureTrees == false) + { - //if we already have tree, exit - if (this.Count > 0) - return; + var foundITrees = PluginManager.Current.ResolveTrees(); - l.UpgradeToWriteLock(); + var objTrees = ApplicationTree.getAll(); + var appTrees = new List(); + appTrees.AddRange(objTrees); + + var apps = Application.getAll(); + + foreach (var type in foundITrees) + { + + //find the Application tree's who's combination of assembly name and tree type is equal to + //the Type that was found's full name. + //Since a tree can exist in multiple applications we'll need to register them all. + + //The logic of this has changed in 6.0: http://issues.umbraco.org/issue/U4-1360 + // we will support the old legacy way but the normal way is to match on assembly qualified names + + var appTreesForType = appTrees.FindAll( + tree => + { + //match the type on assembly qualified name if the assembly attribute is empty or if the + // tree type contains a comma (meaning it is assembly qualified) + if (tree.AssemblyName.IsNullOrWhiteSpace() || tree.Type.Contains(",")) + { + return tree.GetRuntimeType() == type; + } + + //otherwise match using legacy match rules + return (string.Format("{0}.{1}", tree.AssemblyName, tree.Type).InvariantEquals(type.FullName)); + } + ); + + foreach (var appTree in appTreesForType) + { + //find the Application object whos name is the same as our appTree ApplicationAlias + var app = apps.Find( + a => (a.alias == appTree.ApplicationAlias) + ); + + var def = new TreeDefinition(type, appTree, app); + this.Add(def); + } + } + //sort our trees with the sort order definition + this.Sort((t1, t2) => t1.Tree.SortOrder.CompareTo(t2.Tree.SortOrder)); + + _ensureTrees = true; + } + } + } - var foundITrees = PluginManager.Current.ResolveTrees(); - - var objTrees = ApplicationTree.getAll(); - var appTrees = new List(); - appTrees.AddRange(objTrees); - - var apps = Application.getAll(); - - foreach (var type in foundITrees) - { - - //find the Application tree's who's combination of assembly name and tree type is equal to - //the Type that was found's full name. - //Since a tree can exist in multiple applications we'll need to register them all. - - //The logic of this has changed in 6.0: http://issues.umbraco.org/issue/U4-1360 - // we will support the old legacy way but the normal way is to match on assembly qualified names - - var appTreesForType = appTrees.FindAll( - tree => - { - //match the type on assembly qualified name if the assembly attribute is empty or if the - // tree type contains a comma (meaning it is assembly qualified) - if (tree.AssemblyName.IsNullOrWhiteSpace() || tree.Type.Contains(",")) - { - return tree.GetRuntimeType() == type; - } - - //otherwise match using legacy match rules - return (string.Format("{0}.{1}", tree.AssemblyName, tree.Type).InvariantEquals(type.FullName)); - } - ); - - foreach (var appTree in appTreesForType) - { - //find the Application object whos name is the same as our appTree ApplicationAlias - var app = apps.Find( - a => (a.alias == appTree.ApplicationAlias) - ); - - var def = new TreeDefinition(type, appTree, app); - this.Add(def); - } - } - //sort our trees with the sort order definition - this.Sort((t1, t2) => t1.Tree.SortOrder.CompareTo(t2.Tree.SortOrder)); - - } } }