diff --git a/src/Umbraco.Core/ApplicationContext.cs b/src/Umbraco.Core/ApplicationContext.cs
index 1f39c1b9ee..6d4892e911 100644
--- a/src/Umbraco.Core/ApplicationContext.cs
+++ b/src/Umbraco.Core/ApplicationContext.cs
@@ -24,7 +24,7 @@ namespace Umbraco.Core
///
/// Singleton accessor
///
- public static ApplicationContext Current { get; set; }
+ public static ApplicationContext Current { get; internal set; }
// IsReady is set to true by the boot manager once it has successfully booted
// note - the original umbraco module checks on content.Instance in umbraco.dll
diff --git a/src/Umbraco.Web/PluginResolverExtensions.cs b/src/Umbraco.Web/PluginResolverExtensions.cs
index fbbf81c853..102172f15f 100644
--- a/src/Umbraco.Web/PluginResolverExtensions.cs
+++ b/src/Umbraco.Web/PluginResolverExtensions.cs
@@ -7,7 +7,7 @@ using umbraco.BusinessLogic.Utils;
namespace Umbraco.Web
{
- ///
+ ///
/// Extension methods for the PluginResolver
///
public static class PluginResolverExtensions
diff --git a/src/Umbraco.Web/Routing/DocumentRequest.cs b/src/Umbraco.Web/Routing/DocumentRequest.cs
index 65844d84c8..bb51181849 100644
--- a/src/Umbraco.Web/Routing/DocumentRequest.cs
+++ b/src/Umbraco.Web/Routing/DocumentRequest.cs
@@ -251,7 +251,8 @@ namespace Umbraco.Web.Routing
// the first successful lookup, if any, will set this.Node, and may also set this.Template
// some lookups may implement caching
Trace.TraceInformation("{0}Begin lookup", tracePrefix);
- _environment.Lookups.Any(lookup => lookup.LookupDocument(this));
+ var lookups = _environment.RouteLookups.GetLookups();
+ lookups.Any(lookup => lookup.LookupDocument(this));
Trace.TraceInformation("{0}End lookup, {1}", tracePrefix, (this.HasNode ? "a document was found" : "no document was found"));
// fixme - not handling umbracoRedirect
diff --git a/src/Umbraco.Web/Routing/RouteLookups.cs b/src/Umbraco.Web/Routing/RouteLookups.cs
new file mode 100644
index 0000000000..9e6671c9e0
--- /dev/null
+++ b/src/Umbraco.Web/Routing/RouteLookups.cs
@@ -0,0 +1,105 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using Umbraco.Core;
+
+namespace Umbraco.Web.Routing
+{
+ ///
+ /// Represents a collection of ILookups used for routing that are registered in the application
+ ///
+ internal class RouteLookups
+ {
+ private static readonly List Lookups = new List();
+ private static readonly ReaderWriterLockSlim Lock = new ReaderWriterLockSlim();
+
+ ///
+ /// Singleton accessor
+ ///
+ public static RouteLookups Current { get; internal set; }
+
+ internal RouteLookups(IEnumerable lookups)
+ {
+ Lookups.AddRange(SortByWeight(lookups));
+ }
+
+ ///
+ /// Returns all of the lookups
+ ///
+ ///
+ public IEnumerable GetLookups()
+ {
+ return Lookups;
+ }
+
+ ///
+ /// Removes an ILookup based on the specified Type
+ ///
+ ///
+ public void RemoveLookup()
+ where T : ILookup
+ {
+ using (new WriteLock(Lock))
+ {
+ Lookups.Remove(Lookups.SingleOrDefault(x => x is T));
+ }
+ }
+
+ ///
+ /// Adds a new lookup to the end of the list
+ ///
+ ///
+ public void AddLookup(ILookup lookup)
+ {
+ if (CheckExists(lookup))
+ throw new InvalidOperationException("The lookup type " + lookup.GetType() + " already exists in the lookup collection");
+
+ using (new WriteLock(Lock))
+ {
+ Lookups.Add(lookup);
+ }
+ }
+
+ ///
+ /// Inserts a lookup at the specified index
+ ///
+ ///
+ ///
+ public void InsertLookup(int index, ILookup lookup)
+ {
+ if (CheckExists(lookup))
+ throw new InvalidOperationException("The lookup type " + lookup.GetType() + " already exists in the lookup collection");
+
+ using (new WriteLock(Lock))
+ {
+ Lookups.Insert(index, lookup);
+ }
+ }
+
+ ///
+ /// checks if a lookup already exists by type
+ ///
+ ///
+ ///
+ private static bool CheckExists(ILookup lookup)
+ {
+ return Lookups.Any(x => x.GetType() == lookup.GetType());
+ }
+
+ ///
+ /// Sorts the ILookups in the list based on an attribute weight if one is specified
+ ///
+ ///
+ ///
+ private static IEnumerable SortByWeight(IEnumerable lookups)
+ {
+ return lookups.OrderBy(x =>
+ {
+ var attribute = x.GetType().GetCustomAttributes(true).OfType().SingleOrDefault();
+ return attribute == null ? LookupWeightAttribute.DefaultWeight : attribute.Weight;
+ }).ToList();
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Routing/RoutingEnvironment.cs b/src/Umbraco.Web/Routing/RoutingEnvironment.cs
index 0affeb6799..0c5d770e86 100644
--- a/src/Umbraco.Web/Routing/RoutingEnvironment.cs
+++ b/src/Umbraco.Web/Routing/RoutingEnvironment.cs
@@ -11,25 +11,16 @@ namespace Umbraco.Web.Routing
internal class RoutingEnvironment
{
public RoutingEnvironment(
- IEnumerable lookups,
+ RouteLookups lookups,
ILookupNotFound lookupNotFound,
ContentStore contentStore)
{
- Lookups = SortByPartWeight(lookups);
+ RouteLookups = lookups;
LookupNotFound = lookupNotFound;
ContentStore = contentStore;
}
- private static IEnumerable SortByPartWeight(IEnumerable lookups)
- {
- return lookups.OrderBy(x =>
- {
- var attribute = x.GetType().GetCustomAttributes(true).OfType().SingleOrDefault();
- return attribute == null ? LookupWeightAttribute.DefaultWeight : attribute.Weight;
- }).ToList();
- }
-
- public IEnumerable Lookups { get; private set; }
+ public RouteLookups RouteLookups { get; private set; }
public ILookupNotFound LookupNotFound { get; private set; }
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index b3ec0b677e..3b5d82ee48 100644
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -242,6 +242,7 @@
+
diff --git a/src/Umbraco.Web/UmbracoApplication.cs b/src/Umbraco.Web/UmbracoApplication.cs
index 635d873bf5..5febadc78a 100644
--- a/src/Umbraco.Web/UmbracoApplication.cs
+++ b/src/Umbraco.Web/UmbracoApplication.cs
@@ -4,6 +4,7 @@ using System.Diagnostics;
using System.Linq;
using System.Text;
using Umbraco.Core;
+using Umbraco.Web.Routing;
namespace Umbraco.Web
{
@@ -34,6 +35,9 @@ namespace Umbraco.Web
IsReady = true // fixme
};
+ //create the route lookups singleton
+ RouteLookups.Current = new RouteLookups(ApplicationContext.Current.Plugins.ResolveLookups());
+
Trace.TraceInformation("AppDomain is initialized");
}
diff --git a/src/Umbraco.Web/UmbracoModule.cs b/src/Umbraco.Web/UmbracoModule.cs
index 1087e61fe3..bcd976c8d3 100644
--- a/src/Umbraco.Web/UmbracoModule.cs
+++ b/src/Umbraco.Web/UmbracoModule.cs
@@ -42,7 +42,7 @@ namespace Umbraco.Web
var niceUrls = new NiceUrlResolver(contentStore, umbracoContext, RoutesCache.Current.GetProvider());
//create the RoutingEnvironment (one per http request as it relies on the umbraco context!)
var routingEnvironment = new RoutingEnvironment(
- ApplicationContext.Current.Plugins.ResolveLookups().ToArray(),
+ RouteLookups.Current,
new LookupFor404(contentStore),
contentStore);
// create the new document request which will cleanup the uri once and for all