From cc8adae593b9048e091c22266ae2ac8647cbff8f Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 31 Jul 2017 15:07:09 +1000 Subject: [PATCH] Updates ISearchableTree implementation so that a new instance is created per request --- src/Umbraco.Web/Editors/EntityController.cs | 4 +- src/Umbraco.Web/Search/ISearchableTree.cs | 11 +++-- .../Search/SearchableTreeResolver.cs | 42 ++++++++----------- src/Umbraco.Web/Search/UmbracoTreeSearcher.cs | 17 +++++--- .../Trees/ContentTreeController.cs | 4 +- .../Trees/ContentTypeTreeController.cs | 2 +- .../Trees/DataTypeTreeController.cs | 2 +- src/Umbraco.Web/Trees/MediaTreeController.cs | 4 +- .../Trees/MediaTypeTreeController.cs | 2 +- src/Umbraco.Web/Trees/MemberTreeController.cs | 4 +- .../Trees/TemplatesTreeController.cs | 2 +- 11 files changed, 45 insertions(+), 49 deletions(-) diff --git a/src/Umbraco.Web/Editors/EntityController.cs b/src/Umbraco.Web/Editors/EntityController.cs index 71864e8bf7..8bde435ef6 100644 --- a/src/Umbraco.Web/Editors/EntityController.cs +++ b/src/Umbraco.Web/Editors/EntityController.cs @@ -117,7 +117,7 @@ namespace Umbraco.Web.Editors return result; var allowedSections = Security.CurrentUser.AllowedSections.ToArray(); - var searchableTrees = SearchableTreeResolver.Current.SearchableTrees; + var searchableTrees = SearchableTreeResolver.Current.GetSearchableTrees(); foreach (var searchableTree in searchableTrees) { @@ -133,7 +133,7 @@ namespace Umbraco.Web.Editors result[treeAttribute.GetRootNodeDisplayName(Services.TextService)] = new TreeSearchResult { - Results = searchableTree.Value.SearchableTree.Search(Umbraco, query, 200, 0, out total), + Results = searchableTree.Value.SearchableTree.Search(query, 200, 0, out total), TreeAlias = searchableTree.Key, AppAlias = searchableTree.Value.AppAlias, JsFormatterService = searchableTreeAttribute == null ? "" : searchableTreeAttribute.ServiceName, diff --git a/src/Umbraco.Web/Search/ISearchableTree.cs b/src/Umbraco.Web/Search/ISearchableTree.cs index c5eaea2258..6e25724bfa 100644 --- a/src/Umbraco.Web/Search/ISearchableTree.cs +++ b/src/Umbraco.Web/Search/ISearchableTree.cs @@ -14,15 +14,14 @@ namespace Umbraco.Web.Search /// /// Searches for results based on the entity type /// - /// /// - /// - /// - /// A starting point for the search, generally a node id, but for members this is a member type alias - /// /// /// + /// + /// + /// A starting point for the search, generally a node id, but for members this is a member type alias + /// /// - IEnumerable Search(UmbracoHelper umbracoHelper, string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null); + IEnumerable Search(string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null); } } \ No newline at end of file diff --git a/src/Umbraco.Web/Search/SearchableTreeResolver.cs b/src/Umbraco.Web/Search/SearchableTreeResolver.cs index 6c61421400..4831595072 100644 --- a/src/Umbraco.Web/Search/SearchableTreeResolver.cs +++ b/src/Umbraco.Web/Search/SearchableTreeResolver.cs @@ -13,47 +13,39 @@ using Umbraco.Web.Trees; namespace Umbraco.Web.Search { + /// + /// A resolver to return the collection of searchable trees + /// + /// + /// This collection has a request scoped lifetime therefore any instance of ISearchableTree needs to support being a request scoped lifetime + /// public class SearchableTreeResolver : LazyManyObjectsResolverBase { private readonly IApplicationTreeService _treeService; public SearchableTreeResolver(IServiceProvider serviceProvider, ILogger logger, IApplicationTreeService treeService, Func> searchableTrees) - : base(serviceProvider, logger, searchableTrees, ObjectLifetimeScope.Application) + : base(serviceProvider, logger, searchableTrees, ObjectLifetimeScope.HttpRequest) { _treeService = treeService; - } - - private IReadOnlyDictionary _resolved; - private static readonly object Locker = new object(); + } /// /// Returns the a dictionary of tree alias with it's affiliated /// - public IReadOnlyDictionary SearchableTrees + public IReadOnlyDictionary GetSearchableTrees() { - get + var appTrees = _treeService.GetAll().ToArray(); + var collection = new SearchableTreeCollection(); + var searchableTrees = Values.ToArray(); + foreach (var searchableTree in searchableTrees) { - if (_resolved != null) return _resolved; - - lock (Locker) + var found = appTrees.FirstOrDefault(x => x.Alias == searchableTree.TreeAlias); + if (found != null) { - var appTrees = _treeService.GetAll().ToArray(); - var collection = new SearchableTreeCollection(); - var searchableTrees = Values.ToArray(); - foreach (var searchableTree in searchableTrees) - { - var found = appTrees.FirstOrDefault(x => x.Alias == searchableTree.TreeAlias); - if (found != null) - { - collection.Add(new SearchableApplicationTree(found.ApplicationAlias, found.Alias, searchableTree)); - } - } - _resolved = collection.AsReadOnlyDictionary(); - return _resolved; + collection.Add(new SearchableApplicationTree(found.ApplicationAlias, found.Alias, searchableTree)); } } + return collection.AsReadOnlyDictionary(); } - - } } diff --git a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs index 843980e143..0dac79590f 100644 --- a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs +++ b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs @@ -8,6 +8,7 @@ using AutoMapper; using Examine; using Umbraco.Core; using Umbraco.Core.Models; +using Umbraco.Core.Services; using Umbraco.Web.Models.ContentEditing; namespace Umbraco.Web.Search @@ -40,6 +41,9 @@ namespace Umbraco.Web.Search var searcher = Constants.Examine.InternalSearcher; var fields = new[] { "id", "__NodeId" }; + var umbracoContext = umbracoHelper.UmbracoContext; + var appContext = umbracoContext.Application; + //TODO: WE should really just allow passing in a lucene raw query switch (entityType) { @@ -56,13 +60,13 @@ namespace Umbraco.Web.Search break; case UmbracoEntityTypes.Media: type = "media"; - var allMediaStartNodes = umbracoHelper.UmbracoContext.Security.CurrentUser.CalculateMediaStartNodeIds(ApplicationContext.Current.Services.EntityService); - AppendPath(sb, UmbracoObjectTypes.Media, allMediaStartNodes, searchFrom); + var allMediaStartNodes = umbracoContext.Security.CurrentUser.CalculateMediaStartNodeIds(appContext.Services.EntityService); + AppendPath(sb, UmbracoObjectTypes.Media, allMediaStartNodes, searchFrom, appContext.Services.EntityService); break; case UmbracoEntityTypes.Document: type = "content"; - var allContentStartNodes = umbracoHelper.UmbracoContext.Security.CurrentUser.CalculateContentStartNodeIds(ApplicationContext.Current.Services.EntityService); - AppendPath(sb, UmbracoObjectTypes.Document, allContentStartNodes, searchFrom); + var allContentStartNodes = umbracoContext.Security.CurrentUser.CalculateContentStartNodeIds(appContext.Services.EntityService); + AppendPath(sb, UmbracoObjectTypes.Document, allContentStartNodes, searchFrom, appContext.Services.EntityService); break; default: throw new NotSupportedException("The " + typeof(UmbracoTreeSearcher) + " currently does not support searching against object type " + entityType); @@ -199,9 +203,10 @@ namespace Umbraco.Web.Search } } - private void AppendPath(StringBuilder sb, UmbracoObjectTypes objectType, int[] startNodeIds, string searchFrom) + private void AppendPath(StringBuilder sb, UmbracoObjectTypes objectType, int[] startNodeIds, string searchFrom, IEntityService entityService) { - var entityService = ApplicationContext.Current.Services.EntityService; + if (sb == null) throw new ArgumentNullException("sb"); + if (entityService == null) throw new ArgumentNullException("entityService"); int searchFromId; var entityPath = int.TryParse(searchFrom, out searchFromId) && searchFromId > 0 diff --git a/src/Umbraco.Web/Trees/ContentTreeController.cs b/src/Umbraco.Web/Trees/ContentTreeController.cs index 2fc1356f5d..9b3a6e82f8 100644 --- a/src/Umbraco.Web/Trees/ContentTreeController.cs +++ b/src/Umbraco.Web/Trees/ContentTreeController.cs @@ -259,9 +259,9 @@ namespace Umbraco.Web.Trees return menu; } - public IEnumerable Search(UmbracoHelper umbracoHelper, string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null) + public IEnumerable Search(string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null) { - return _treeSearcher.ExamineSearch(umbracoHelper, query, UmbracoEntityTypes.Document, pageSize, pageIndex, out totalFound, searchFrom); + return _treeSearcher.ExamineSearch(Umbraco, query, UmbracoEntityTypes.Document, pageSize, pageIndex, out totalFound, searchFrom); } } } \ No newline at end of file diff --git a/src/Umbraco.Web/Trees/ContentTypeTreeController.cs b/src/Umbraco.Web/Trees/ContentTypeTreeController.cs index f6b3231f66..7f3a6dfddf 100644 --- a/src/Umbraco.Web/Trees/ContentTypeTreeController.cs +++ b/src/Umbraco.Web/Trees/ContentTypeTreeController.cs @@ -142,7 +142,7 @@ namespace Umbraco.Web.Trees return menu; } - public IEnumerable Search(UmbracoHelper umbracoHelper, string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null) + public IEnumerable Search(string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null) { var results = Services.EntityService.GetPagedDescendantsFromRoot(UmbracoObjectTypes.DocumentType, pageIndex, pageSize, out totalFound, filter: query); return Mapper.Map>(results); diff --git a/src/Umbraco.Web/Trees/DataTypeTreeController.cs b/src/Umbraco.Web/Trees/DataTypeTreeController.cs index e635e84fd1..b19d79c817 100644 --- a/src/Umbraco.Web/Trees/DataTypeTreeController.cs +++ b/src/Umbraco.Web/Trees/DataTypeTreeController.cs @@ -127,7 +127,7 @@ namespace Umbraco.Web.Trees return menu; } - public IEnumerable Search(UmbracoHelper umbracoHelper, string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null) + public IEnumerable Search(string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null) { var results = Services.EntityService.GetPagedDescendantsFromRoot(UmbracoObjectTypes.DataType, pageIndex, pageSize, out totalFound, filter: query); return Mapper.Map>(results); diff --git a/src/Umbraco.Web/Trees/MediaTreeController.cs b/src/Umbraco.Web/Trees/MediaTreeController.cs index 114aa9cf2f..679d4a2d6a 100644 --- a/src/Umbraco.Web/Trees/MediaTreeController.cs +++ b/src/Umbraco.Web/Trees/MediaTreeController.cs @@ -173,9 +173,9 @@ namespace Umbraco.Web.Trees return Security.CurrentUser.HasPathAccess(media, Services.EntityService); } - public IEnumerable Search(UmbracoHelper umbracoHelper, string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null) + public IEnumerable Search(string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null) { - return _treeSearcher.ExamineSearch(umbracoHelper, query, UmbracoEntityTypes.Media, pageSize, pageIndex, out totalFound, searchFrom); + return _treeSearcher.ExamineSearch(Umbraco, query, UmbracoEntityTypes.Media, pageSize, pageIndex, out totalFound, searchFrom); } } } \ No newline at end of file diff --git a/src/Umbraco.Web/Trees/MediaTypeTreeController.cs b/src/Umbraco.Web/Trees/MediaTypeTreeController.cs index 4708b7d79c..e402b5d64b 100644 --- a/src/Umbraco.Web/Trees/MediaTypeTreeController.cs +++ b/src/Umbraco.Web/Trees/MediaTypeTreeController.cs @@ -129,7 +129,7 @@ namespace Umbraco.Web.Trees return menu; } - public IEnumerable Search(UmbracoHelper umbracoHelper, string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null) + public IEnumerable Search(string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null) { var results = Services.EntityService.GetPagedDescendantsFromRoot(UmbracoObjectTypes.MediaType, pageIndex, pageSize, out totalFound, filter: query); return Mapper.Map>(results); diff --git a/src/Umbraco.Web/Trees/MemberTreeController.cs b/src/Umbraco.Web/Trees/MemberTreeController.cs index cc294b7fb3..68f12ef6ca 100644 --- a/src/Umbraco.Web/Trees/MemberTreeController.cs +++ b/src/Umbraco.Web/Trees/MemberTreeController.cs @@ -184,9 +184,9 @@ namespace Umbraco.Web.Trees return menu; } - public IEnumerable Search(UmbracoHelper umbracoHelper, string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null) + public IEnumerable Search(string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null) { - return _treeSearcher.ExamineSearch(umbracoHelper, query, UmbracoEntityTypes.Member, pageSize, pageIndex, out totalFound, searchFrom); + return _treeSearcher.ExamineSearch(Umbraco, query, UmbracoEntityTypes.Member, pageSize, pageIndex, out totalFound, searchFrom); } } } \ No newline at end of file diff --git a/src/Umbraco.Web/Trees/TemplatesTreeController.cs b/src/Umbraco.Web/Trees/TemplatesTreeController.cs index 303d47f307..c5c3c3dc70 100644 --- a/src/Umbraco.Web/Trees/TemplatesTreeController.cs +++ b/src/Umbraco.Web/Trees/TemplatesTreeController.cs @@ -133,7 +133,7 @@ namespace Umbraco.Web.Trees : null; } - public IEnumerable Search(UmbracoHelper umbracoHelper, string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null) + public IEnumerable Search(string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null) { var results = Services.EntityService.GetPagedDescendantsFromRoot(UmbracoObjectTypes.Template, pageIndex, pageSize, out totalFound, filter: query); return Mapper.Map>(results);