Added singleton for managing ILookups collection, allows for adding/removing/inserting at runtime/startup
This commit is contained in:
@@ -24,7 +24,7 @@ namespace Umbraco.Core
|
||||
/// <summary>
|
||||
/// Singleton accessor
|
||||
/// </summary>
|
||||
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
|
||||
|
||||
@@ -7,7 +7,7 @@ using umbraco.BusinessLogic.Utils;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Extension methods for the PluginResolver
|
||||
/// </summary>
|
||||
public static class PluginResolverExtensions
|
||||
|
||||
@@ -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
|
||||
|
||||
105
src/Umbraco.Web/Routing/RouteLookups.cs
Normal file
105
src/Umbraco.Web/Routing/RouteLookups.cs
Normal file
@@ -0,0 +1,105 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Umbraco.Core;
|
||||
|
||||
namespace Umbraco.Web.Routing
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a collection of ILookups used for routing that are registered in the application
|
||||
/// </summary>
|
||||
internal class RouteLookups
|
||||
{
|
||||
private static readonly List<ILookup> Lookups = new List<ILookup>();
|
||||
private static readonly ReaderWriterLockSlim Lock = new ReaderWriterLockSlim();
|
||||
|
||||
/// <summary>
|
||||
/// Singleton accessor
|
||||
/// </summary>
|
||||
public static RouteLookups Current { get; internal set; }
|
||||
|
||||
internal RouteLookups(IEnumerable<ILookup> lookups)
|
||||
{
|
||||
Lookups.AddRange(SortByWeight(lookups));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all of the lookups
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<ILookup> GetLookups()
|
||||
{
|
||||
return Lookups;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes an ILookup based on the specified Type
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public void RemoveLookup<T>()
|
||||
where T : ILookup
|
||||
{
|
||||
using (new WriteLock(Lock))
|
||||
{
|
||||
Lookups.Remove(Lookups.SingleOrDefault(x => x is T));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new lookup to the end of the list
|
||||
/// </summary>
|
||||
/// <param name="lookup"></param>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a lookup at the specified index
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="lookup"></param>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// checks if a lookup already exists by type
|
||||
/// </summary>
|
||||
/// <param name="lookup"></param>
|
||||
/// <returns></returns>
|
||||
private static bool CheckExists(ILookup lookup)
|
||||
{
|
||||
return Lookups.Any(x => x.GetType() == lookup.GetType());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sorts the ILookups in the list based on an attribute weight if one is specified
|
||||
/// </summary>
|
||||
/// <param name="lookups"></param>
|
||||
/// <returns></returns>
|
||||
private static IEnumerable<ILookup> SortByWeight(IEnumerable<ILookup> lookups)
|
||||
{
|
||||
return lookups.OrderBy(x =>
|
||||
{
|
||||
var attribute = x.GetType().GetCustomAttributes(true).OfType<LookupWeightAttribute>().SingleOrDefault();
|
||||
return attribute == null ? LookupWeightAttribute.DefaultWeight : attribute.Weight;
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -11,25 +11,16 @@ namespace Umbraco.Web.Routing
|
||||
internal class RoutingEnvironment
|
||||
{
|
||||
public RoutingEnvironment(
|
||||
IEnumerable<ILookup> lookups,
|
||||
RouteLookups lookups,
|
||||
ILookupNotFound lookupNotFound,
|
||||
ContentStore contentStore)
|
||||
{
|
||||
Lookups = SortByPartWeight(lookups);
|
||||
RouteLookups = lookups;
|
||||
LookupNotFound = lookupNotFound;
|
||||
ContentStore = contentStore;
|
||||
}
|
||||
|
||||
private static IEnumerable<ILookup> SortByPartWeight(IEnumerable<ILookup> lookups)
|
||||
{
|
||||
return lookups.OrderBy(x =>
|
||||
{
|
||||
var attribute = x.GetType().GetCustomAttributes(true).OfType<LookupWeightAttribute>().SingleOrDefault();
|
||||
return attribute == null ? LookupWeightAttribute.DefaultWeight : attribute.Weight;
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
public IEnumerable<ILookup> Lookups { get; private set; }
|
||||
public RouteLookups RouteLookups { get; private set; }
|
||||
|
||||
public ILookupNotFound LookupNotFound { get; private set; }
|
||||
|
||||
|
||||
@@ -242,6 +242,7 @@
|
||||
<Compile Include="Mvc\ControllerExtensions.cs" />
|
||||
<Compile Include="NiceUrlResolver.cs" />
|
||||
<Compile Include="PluginResolverExtensions.cs" />
|
||||
<Compile Include="Routing\RouteLookups.cs" />
|
||||
<Compile Include="Routing\DocumentRequest.cs" />
|
||||
<Compile Include="Routing\ILookup.cs" />
|
||||
<Compile Include="Routing\ILookupNotFound.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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user