From 6d45f9da746dd0f349360109236920343974da6e Mon Sep 17 00:00:00 2001 From: Steve Bohlen Date: Mon, 2 Feb 2015 18:47:02 -0500 Subject: [PATCH] rework MVC dependency-resolver to more effectively short-circuit expensive type resolution when no need to continue to interrogate the context further --- .../SpringMvcDependencyResolver.cs | 53 ++++++++++++++++--- 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/src/Spring/Spring.Web.Mvc3/SpringMvcDependencyResolver.cs b/src/Spring/Spring.Web.Mvc3/SpringMvcDependencyResolver.cs index 67f6e8d4..c2609889 100644 --- a/src/Spring/Spring.Web.Mvc3/SpringMvcDependencyResolver.cs +++ b/src/Spring/Spring.Web.Mvc3/SpringMvcDependencyResolver.cs @@ -1,7 +1,13 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Web.Mvc; + +using Common.Logging; + +using Microsoft.Win32; + using Spring.Context; using Spring.Context.Support; @@ -13,11 +19,15 @@ namespace Spring.Web.Mvc public class SpringMvcDependencyResolver : IDependencyResolver { private static readonly string IgnoreViewNamespace = "ASP."; + /// /// The to be used by the resolver /// private IApplicationContext _context; + private static readonly ILog logger = LogManager.GetLogger(typeof(SpringMvcDependencyResolver)); + private readonly ConcurrentBag _nonResolvableTypes = new ConcurrentBag(); + /// /// Initializes a new instance of the class. /// @@ -72,15 +82,45 @@ namespace Spring.Web.Mvc { object service = null; - if (serviceType != null && !serviceType.FullName.StartsWith(IgnoreViewNamespace)) + if (serviceType != null) { - var services = ApplicationContext.GetObjectsOfType(serviceType); - if (services.Count > 0) + //if its an MVC auto-generated View Class... + if (serviceType.FullName.StartsWith(IgnoreViewNamespace)) { - service = services.First().Value; + return null; + } + + //if we already know the container has tried and failed to resolve the type prior... + if (_nonResolvableTypes.Contains(serviceType)) + { + return null; + } + + // fastest lookup is if we have direct name match + if (_context.ContainsObjectDefinition(serviceType.Name)) + { + service = _context.GetObject(serviceType.Name); + } + else + { + // fall back to more expensive searching with type + var matchingServices = _context.GetObjectNamesForType(serviceType); + if (matchingServices.Count > 0) + { + service = _context.GetObject(matchingServices[0]); + } + } + + if (service == null) + { + _nonResolvableTypes.Add(serviceType); + + if (logger.IsDebugEnabled) + { + logger.DebugFormat("could not find service from Spring container with type: {0}", serviceType); + } } } - return service; } @@ -91,8 +131,7 @@ namespace Spring.Web.Mvc /// The requested services. public IEnumerable GetServices(Type serviceType) { - var services = ApplicationContext.GetObjectsOfType(serviceType); - return services.Values; + return ApplicationContext.GetObjectsOfType(serviceType).Values; } } }