From fe31ed5cb24742c117eee8706b55acb89a51afd1 Mon Sep 17 00:00:00 2001 From: filipw Date: Tue, 21 Oct 2014 08:37:40 +0200 Subject: [PATCH 1/2] changed NamespaceHttpControllerSelector to use a helper class NamespaceHttpControllerMetadata rather than raw Type caching --- .../WebApi/NamespaceHttpControllerSelector.cs | 58 ++++++++++++++++--- 1 file changed, 49 insertions(+), 9 deletions(-) diff --git a/src/Umbraco.Web/WebApi/NamespaceHttpControllerSelector.cs b/src/Umbraco.Web/WebApi/NamespaceHttpControllerSelector.cs index dd75decc11..975561afff 100644 --- a/src/Umbraco.Web/WebApi/NamespaceHttpControllerSelector.cs +++ b/src/Umbraco.Web/WebApi/NamespaceHttpControllerSelector.cs @@ -62,22 +62,62 @@ namespace Umbraco.Web.WebApi return new HttpControllerDescriptor(_configuration, controllerNameAsString, found); } - private IEnumerable GetDuplicateControllerTypes() + private ConcurrentStack GetDuplicateControllerTypes() { var assembliesResolver = _configuration.Services.GetAssembliesResolver(); var controllersResolver = _configuration.Services.GetHttpControllerTypeResolver(); var controllerTypes = controllersResolver.GetControllerTypes(assembliesResolver); - //we have all controller types, so just store the ones with duplicate class names - we don't - // want to cache too much and the underlying selector caches everything else + var groupedByName = controllerTypes.GroupBy( + t => t.Name.Substring(0, t.Name.Length - ControllerSuffix.Length), + StringComparer.OrdinalIgnoreCase).Where(x => x.Count() > 1); - var duplicates = controllerTypes.GroupBy(x => x.Name) - .Where(x => x.Count() > 1) - .SelectMany(x => x) - .ToArray(); + var duplicateControllers = groupedByName.ToDictionary( + g => g.Key, + g => g.ToLookup(t => t.Namespace ?? String.Empty, StringComparer.OrdinalIgnoreCase), + StringComparer.OrdinalIgnoreCase); - return duplicates; + var result = new ConcurrentStack(); + + foreach (var controllerTypeGroup in duplicateControllers) + { + foreach (var controllerType in controllerTypeGroup.Value.SelectMany(controllerTypesGrouping => controllerTypesGrouping)) + { + result.Push(new NamespaceHttpControllerMetadata(controllerTypeGroup.Key, controllerType.Namespace, + new HttpControllerDescriptor(_configuration, controllerTypeGroup.Key, controllerType))); + } + } + + return result; + } + + private class NamespaceHttpControllerMetadata + { + private readonly string _controllerName; + private readonly string _controllerNamespace; + private readonly HttpControllerDescriptor _descriptor; + + public NamespaceHttpControllerMetadata(string controllerName, string controllerNamespace, HttpControllerDescriptor descriptor) + { + _controllerName = controllerName; + _controllerNamespace = controllerNamespace; + _descriptor = descriptor; + } + + public string ControllerName + { + get { return _controllerName; } + } + + public string ControllerNamespace + { + get { return _controllerNamespace; } + } + + public HttpControllerDescriptor Descriptor + { + get { return _descriptor; } + } } - } } \ No newline at end of file From 9e7d2884b9abe7bc18da22330abb2e782a0e50eb Mon Sep 17 00:00:00 2001 From: filipw Date: Tue, 21 Oct 2014 08:39:21 +0200 Subject: [PATCH 2/2] do not recreate HttpControllerDescriptor every time --- .../WebApi/NamespaceHttpControllerSelector.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Web/WebApi/NamespaceHttpControllerSelector.cs b/src/Umbraco.Web/WebApi/NamespaceHttpControllerSelector.cs index 975561afff..1447085dc2 100644 --- a/src/Umbraco.Web/WebApi/NamespaceHttpControllerSelector.cs +++ b/src/Umbraco.Web/WebApi/NamespaceHttpControllerSelector.cs @@ -14,12 +14,12 @@ namespace Umbraco.Web.WebApi { private const string ControllerKey = "controller"; private readonly HttpConfiguration _configuration; - private readonly Lazy> _duplicateControllerTypes; + private readonly Lazy> _duplicateControllerTypes; public NamespaceHttpControllerSelector(HttpConfiguration configuration) : base(configuration) { _configuration = configuration; - _duplicateControllerTypes = new Lazy>(GetDuplicateControllerTypes); + _duplicateControllerTypes = new Lazy>(GetDuplicateControllerTypes); } public override HttpControllerDescriptor SelectController(HttpRequestMessage request) @@ -52,14 +52,11 @@ namespace Umbraco.Web.WebApi return base.SelectController(request); //see if this is in our cache - var found = _duplicateControllerTypes.Value - .Where(x => string.Equals(x.Name, controllerNameAsString + ControllerSuffix, StringComparison.OrdinalIgnoreCase)) - .FirstOrDefault(x => namespaces.Contains(x.Namespace)); - + var found = _duplicateControllerTypes.Value.FirstOrDefault(x => string.Equals(x.ControllerName, controllerNameAsString, StringComparison.OrdinalIgnoreCase) && namespaces.Contains(x.ControllerNamespace)); if (found == null) return base.SelectController(request); - return new HttpControllerDescriptor(_configuration, controllerNameAsString, found); + return found.Descriptor; } private ConcurrentStack GetDuplicateControllerTypes()