Added singleton for managing ILookups collection, allows for adding/removing/inserting at runtime/startup

This commit is contained in:
shannon@ShandemVaio
2012-07-20 23:42:55 +06:00
parent 6c872e8a65
commit 8f278bcaa5
8 changed files with 118 additions and 16 deletions

View File

@@ -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

View File

@@ -7,7 +7,7 @@ using umbraco.BusinessLogic.Utils;
namespace Umbraco.Web
{
/// <summary>
/// <summary>
/// Extension methods for the PluginResolver
/// </summary>
public static class PluginResolverExtensions

View File

@@ -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

View 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();
}
}
}

View File

@@ -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; }

View File

@@ -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" />

View File

@@ -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");
}

View File

@@ -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