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>
|
/// <summary>
|
||||||
/// Singleton accessor
|
/// Singleton accessor
|
||||||
/// </summary>
|
/// </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
|
// 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
|
// note - the original umbraco module checks on content.Instance in umbraco.dll
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using umbraco.BusinessLogic.Utils;
|
|||||||
|
|
||||||
namespace Umbraco.Web
|
namespace Umbraco.Web
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Extension methods for the PluginResolver
|
/// Extension methods for the PluginResolver
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class PluginResolverExtensions
|
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
|
// the first successful lookup, if any, will set this.Node, and may also set this.Template
|
||||||
// some lookups may implement caching
|
// some lookups may implement caching
|
||||||
Trace.TraceInformation("{0}Begin lookup", tracePrefix);
|
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"));
|
Trace.TraceInformation("{0}End lookup, {1}", tracePrefix, (this.HasNode ? "a document was found" : "no document was found"));
|
||||||
|
|
||||||
// fixme - not handling umbracoRedirect
|
// 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
|
internal class RoutingEnvironment
|
||||||
{
|
{
|
||||||
public RoutingEnvironment(
|
public RoutingEnvironment(
|
||||||
IEnumerable<ILookup> lookups,
|
RouteLookups lookups,
|
||||||
ILookupNotFound lookupNotFound,
|
ILookupNotFound lookupNotFound,
|
||||||
ContentStore contentStore)
|
ContentStore contentStore)
|
||||||
{
|
{
|
||||||
Lookups = SortByPartWeight(lookups);
|
RouteLookups = lookups;
|
||||||
LookupNotFound = lookupNotFound;
|
LookupNotFound = lookupNotFound;
|
||||||
ContentStore = contentStore;
|
ContentStore = contentStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IEnumerable<ILookup> SortByPartWeight(IEnumerable<ILookup> lookups)
|
public RouteLookups RouteLookups { get; private set; }
|
||||||
{
|
|
||||||
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 ILookupNotFound LookupNotFound { get; private set; }
|
public ILookupNotFound LookupNotFound { get; private set; }
|
||||||
|
|
||||||
|
|||||||
@@ -242,6 +242,7 @@
|
|||||||
<Compile Include="Mvc\ControllerExtensions.cs" />
|
<Compile Include="Mvc\ControllerExtensions.cs" />
|
||||||
<Compile Include="NiceUrlResolver.cs" />
|
<Compile Include="NiceUrlResolver.cs" />
|
||||||
<Compile Include="PluginResolverExtensions.cs" />
|
<Compile Include="PluginResolverExtensions.cs" />
|
||||||
|
<Compile Include="Routing\RouteLookups.cs" />
|
||||||
<Compile Include="Routing\DocumentRequest.cs" />
|
<Compile Include="Routing\DocumentRequest.cs" />
|
||||||
<Compile Include="Routing\ILookup.cs" />
|
<Compile Include="Routing\ILookup.cs" />
|
||||||
<Compile Include="Routing\ILookupNotFound.cs" />
|
<Compile Include="Routing\ILookupNotFound.cs" />
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System.Diagnostics;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Umbraco.Core;
|
using Umbraco.Core;
|
||||||
|
using Umbraco.Web.Routing;
|
||||||
|
|
||||||
namespace Umbraco.Web
|
namespace Umbraco.Web
|
||||||
{
|
{
|
||||||
@@ -34,6 +35,9 @@ namespace Umbraco.Web
|
|||||||
IsReady = true // fixme
|
IsReady = true // fixme
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//create the route lookups singleton
|
||||||
|
RouteLookups.Current = new RouteLookups(ApplicationContext.Current.Plugins.ResolveLookups());
|
||||||
|
|
||||||
Trace.TraceInformation("AppDomain is initialized");
|
Trace.TraceInformation("AppDomain is initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ namespace Umbraco.Web
|
|||||||
var niceUrls = new NiceUrlResolver(contentStore, umbracoContext, RoutesCache.Current.GetProvider());
|
var niceUrls = new NiceUrlResolver(contentStore, umbracoContext, RoutesCache.Current.GetProvider());
|
||||||
//create the RoutingEnvironment (one per http request as it relies on the umbraco context!)
|
//create the RoutingEnvironment (one per http request as it relies on the umbraco context!)
|
||||||
var routingEnvironment = new RoutingEnvironment(
|
var routingEnvironment = new RoutingEnvironment(
|
||||||
ApplicationContext.Current.Plugins.ResolveLookups().ToArray(),
|
RouteLookups.Current,
|
||||||
new LookupFor404(contentStore),
|
new LookupFor404(contentStore),
|
||||||
contentStore);
|
contentStore);
|
||||||
// create the new document request which will cleanup the uri once and for all
|
// create the new document request which will cleanup the uri once and for all
|
||||||
|
|||||||
Reference in New Issue
Block a user