2012-08-01 22:06:15 +06:00
using System ;
2012-08-07 21:40:34 +06:00
using System.Collections.Generic ;
2013-11-28 14:27:58 +11:00
using System.Collections.Specialized ;
2014-01-09 15:58:06 +11:00
using System.Configuration ;
2012-09-26 11:04:07 +07:00
using System.Linq ;
2013-03-11 23:46:47 +06:00
using System.Web ;
2014-01-09 15:58:06 +11:00
using System.Web.Configuration ;
2013-02-26 03:45:39 +06:00
using System.Web.Http ;
2014-06-27 13:34:15 +10:00
using System.Web.Http.Dispatcher ;
2012-08-07 21:40:34 +06:00
using System.Web.Mvc ;
using System.Web.Routing ;
2013-11-28 14:27:58 +11:00
using ClientDependency.Core.Config ;
2014-12-09 19:07:14 +11:00
using Examine ;
2015-07-24 18:52:04 +02:00
using Examine.Config ;
2015-03-04 12:16:28 +01:00
using umbraco ;
2012-08-01 22:06:15 +06:00
using Umbraco.Core ;
2012-09-25 13:09:59 +07:00
using Umbraco.Core.Configuration ;
2012-08-15 23:20:37 +06:00
using Umbraco.Core.Dictionary ;
2013-02-12 03:46:27 +06:00
using Umbraco.Core.Logging ;
2013-08-29 17:14:34 +10:00
using Umbraco.Core.Macros ;
2013-01-29 09:45:12 +06:00
using Umbraco.Core.ObjectResolution ;
2013-05-12 15:25:46 -10:00
using Umbraco.Core.Profiling ;
2012-09-08 07:13:03 +07:00
using Umbraco.Core.PropertyEditors ;
2013-09-23 16:30:24 +02:00
using Umbraco.Core.PropertyEditors.ValueConverters ;
2013-02-12 03:46:27 +06:00
using Umbraco.Core.Sync ;
2012-08-15 23:20:37 +06:00
using Umbraco.Web.Dictionary ;
2014-02-26 04:15:14 +11:00
using Umbraco.Web.Install ;
2013-08-29 17:14:34 +10:00
using Umbraco.Web.Macros ;
2012-11-21 07:14:40 -01:00
using Umbraco.Web.Media ;
2012-08-04 06:20:06 +06:00
using Umbraco.Web.Media.ThumbnailProviders ;
2012-10-24 09:59:23 +05:00
using Umbraco.Web.Models ;
2012-08-07 21:40:34 +06:00
using Umbraco.Web.Mvc ;
2012-09-08 07:13:03 +07:00
using Umbraco.Web.PropertyEditors ;
2013-09-23 16:30:24 +02:00
using Umbraco.Web.PropertyEditors.ValueConverters ;
2013-02-05 06:31:13 -01:00
using Umbraco.Web.PublishedCache ;
2012-08-01 22:06:15 +06:00
using Umbraco.Web.Routing ;
2013-07-31 18:21:27 +10:00
using Umbraco.Web.Security ;
2014-06-20 14:34:21 +10:00
using Umbraco.Web.Scheduling ;
2013-11-28 14:27:58 +11:00
using Umbraco.Web.UI.JavaScript ;
2013-02-26 22:14:32 +06:00
using Umbraco.Web.WebApi ;
2013-02-12 03:46:27 +06:00
using umbraco.BusinessLogic ;
2015-07-23 20:04:40 +02:00
using Umbraco.Core.Persistence ;
using Umbraco.Core.Persistence.UnitOfWork ;
using Umbraco.Core.Publishing ;
using Umbraco.Core.Services ;
2015-03-04 12:16:28 +01:00
using GlobalSettings = Umbraco . Core . Configuration . GlobalSettings ;
2013-10-02 17:48:44 +02:00
using ProfilingViewEngine = Umbraco . Core . Profiling . ProfilingViewEngine ;
2012-08-01 22:06:15 +06:00
2012-09-25 13:09:59 +07:00
2012-08-01 22:06:15 +06:00
namespace Umbraco.Web
{
2013-01-18 08:47:38 -01:00
/// <summary>
/// A bootstrapper for the Umbraco application which initializes all objects including the Web portion of the application
/// </summary>
2013-01-27 12:59:41 -01:00
public class WebBootManager : CoreBootManager
2013-01-18 08:47:38 -01:00
{
private readonly bool _isForTesting ;
2014-12-09 19:07:14 +11:00
//NOTE: see the Initialize method for what this is used for
2015-03-04 12:16:28 +01:00
private readonly List < IIndexer > _indexesToRebuild = new List < IIndexer > ( ) ;
2013-01-18 08:47:38 -01:00
2013-06-18 14:59:00 +10:00
public WebBootManager ( UmbracoApplicationBase umbracoApplication )
2015-07-22 12:44:29 +02:00
: base ( umbracoApplication )
2013-01-18 08:47:38 -01:00
{
2015-07-22 12:44:29 +02:00
_isForTesting = false ;
2013-01-18 08:47:38 -01:00
}
/// <summary>
/// Constructor for unit tests, ensures some resolvers are not initialized
/// </summary>
/// <param name="umbracoApplication"></param>
2015-07-22 12:44:29 +02:00
/// <param name="logger"></param>
2013-01-18 08:47:38 -01:00
/// <param name="isForTesting"></param>
2015-07-22 12:44:29 +02:00
internal WebBootManager ( UmbracoApplicationBase umbracoApplication , ProfilingLogger logger , bool isForTesting )
: base ( umbracoApplication , logger )
2013-01-18 08:47:38 -01:00
{
2013-06-18 14:59:00 +10:00
_isForTesting = isForTesting ;
2013-01-18 08:47:38 -01:00
}
2015-07-23 20:04:40 +02:00
/// <summary>
/// Creates and returns the service context for the app
/// </summary>
/// <param name="dbContext"></param>
/// <param name="dbFactory"></param>
/// <returns></returns>
protected override ServiceContext CreateServiceContext ( DatabaseContext dbContext , IDatabaseFactory dbFactory )
{
return new ServiceContext (
new RepositoryFactory ( ApplicationCache , ProfilingLogger . Logger , dbContext . SqlSyntax , UmbracoConfig . For . UmbracoSettings ( ) ) ,
new PetaPocoUnitOfWorkProvider ( dbFactory ) ,
new FileUnitOfWorkProvider ( ) ,
new PublishingStrategy ( ) ,
ApplicationCache ,
ProfilingLogger . Logger ,
//use a request based messaging factory
new RequestLifespanMessagesFactory ( new SingletonUmbracoContextAccessor ( ) ) ) ;
}
2013-01-18 08:47:38 -01:00
/// <summary>
/// Initialize objects before anything during the boot cycle happens
/// </summary>
/// <returns></returns>
public override IBootManager Initialize ( )
2013-06-18 14:59:00 +10:00
{
2014-12-09 19:07:14 +11:00
//This is basically a hack for this item: http://issues.umbraco.org/issue/U4-5976
// when Examine initializes it will try to rebuild if the indexes are empty, however in many cases not all of Examine's
// event handlers will be assigned during bootup when the rebuilding starts which is a problem. So with the examine 0.1.58.2941 build
// it has an event we can subscribe to in order to cancel this rebuilding process, but what we'll do is cancel it and postpone the rebuilding until the
// boot process has completed. It's a hack but it works.
ExamineManager . Instance . BuildingEmptyIndexOnStartup + = OnInstanceOnBuildingEmptyIndexOnStartup ;
2013-01-18 08:47:38 -01:00
base . Initialize ( ) ;
// Backwards compatibility - set the path and URL type for ClientDependency 1.5.1 [LK]
ClientDependency . Core . CompositeFiles . Providers . XmlFileMapper . FileMapVirtualFolder = "~/App_Data/TEMP/ClientDependency" ;
ClientDependency . Core . CompositeFiles . Providers . BaseCompositeFileProcessingProvider . UrlTypeDefault = ClientDependency . Core . CompositeFiles . Providers . CompositeUrlType . Base64QueryStrings ;
2014-01-09 15:58:06 +11:00
var section = ConfigurationManager . GetSection ( "system.web/httpRuntime" ) as HttpRuntimeSection ;
if ( section ! = null )
{
//set the max url length for CDF to be the smallest of the max query length, max request length
ClientDependency . Core . CompositeFiles . CompositeDependencyHandler . MaxHandlerUrlLength = Math . Min ( section . MaxQueryStringLength , section . MaxRequestLength ) ;
}
2013-01-18 08:47:38 -01:00
//set master controller factory
ControllerBuilder . Current . SetControllerFactory (
new MasterControllerFactory ( FilteredControllerFactoriesResolver . Current ) ) ;
//set the render view engine
2013-10-02 17:48:44 +02:00
ViewEngines . Engines . Add ( new RenderViewEngine ( ) ) ;
2013-01-18 08:47:38 -01:00
//set the plugin view engine
2013-10-02 17:48:44 +02:00
ViewEngines . Engines . Add ( new PluginViewEngine ( ) ) ;
2013-01-18 08:47:38 -01:00
//set model binder
ModelBinders . Binders . Add ( new KeyValuePair < Type , IModelBinder > ( typeof ( RenderModel ) , new RenderModelBinder ( ) ) ) ;
2014-06-09 15:32:44 +02:00
////add the profiling action filter
//GlobalFilters.Filters.Add(new ProfilingActionFilter());
2013-11-28 14:27:58 +11:00
//Register a custom renderer - used to process property editor dependencies
var renderer = new DependencyPathRenderer ( ) ;
2015-03-18 19:04:49 +11:00
renderer . Initialize ( "Umbraco.DependencyPathRenderer" , new NameValueCollection
{
{ "compositeFileHandlerPath" , ClientDependencySettings . Instance . CompositeFileHandlerPath }
} ) ;
2013-11-28 14:27:58 +11:00
ClientDependencySettings . Instance . MvcRendererCollection . Add ( renderer ) ;
2015-03-18 19:04:49 +11:00
2013-11-28 14:27:58 +11:00
2014-03-07 12:09:30 +01:00
InstallHelper insHelper = new InstallHelper ( UmbracoContext . Current ) ;
insHelper . DeleteLegacyInstaller ( ) ;
2013-01-18 08:47:38 -01:00
return this ;
}
2014-12-09 19:07:14 +11:00
2013-03-11 23:46:47 +06:00
/// <summary>
/// Override this method in order to ensure that the UmbracoContext is also created, this can only be
/// created after resolution is frozen!
/// </summary>
protected override void FreezeResolution ( )
{
base . FreezeResolution ( ) ;
//before we do anything, we'll ensure the umbraco context
//see: http://issues.umbraco.org/issue/U4-1717
2013-07-31 18:21:27 +10:00
var httpContext = new HttpContextWrapper ( UmbracoApplication . Context ) ;
UmbracoContext . EnsureContext (
2014-02-26 04:15:14 +11:00
httpContext ,
2013-07-31 18:21:27 +10:00
ApplicationContext ,
2015-07-22 12:44:29 +02:00
new WebSecurity ( httpContext , ApplicationContext ) ,
UmbracoConfig . For . UmbracoSettings ( ) ,
UrlProviderResolver . Current . Providers ,
false ) ;
2013-03-11 23:46:47 +06:00
}
2013-05-13 21:11:03 -10:00
/// <summary>
/// Ensure the current profiler is the web profiler
/// </summary>
protected override void InitializeProfilerResolver ( )
{
base . InitializeProfilerResolver ( ) ;
//Set the profiler to be the web profiler
ProfilerResolver . Current . SetProfiler ( new WebProfiler ( ) ) ;
}
2015-07-23 20:04:40 +02:00
2013-01-18 08:47:38 -01:00
/// <summary>
/// Ensure that the OnApplicationStarted methods of the IApplicationEvents are called
/// </summary>
/// <param name="afterComplete"></param>
/// <returns></returns>
public override IBootManager Complete ( Action < ApplicationContext > afterComplete )
{
2014-02-26 04:15:14 +11:00
//Wrap viewengines in the profiling engine
WrapViewEngines ( ViewEngines . Engines ) ;
2013-10-02 17:48:44 +02:00
2014-02-26 04:15:14 +11:00
//set routes
2013-01-18 08:47:38 -01:00
CreateRoutes ( ) ;
base . Complete ( afterComplete ) ;
2013-02-14 23:26:29 +06:00
//Now, startup all of our legacy startup handler
2013-04-16 04:27:03 -02:00
ApplicationEventsResolver . Current . InstantiateLegacyStartupHandlers ( ) ;
2014-12-09 19:07:14 +11:00
//Ok, now that everything is complete we'll check if we've stored any references to index that need rebuilding and run them
// (see the initialize method for notes) - we'll ensure we remove the event handler too in case examine manager doesn't actually
// initialize during startup, in which case we want it to rebuild the indexes itself.
ExamineManager . Instance . BuildingEmptyIndexOnStartup - = OnInstanceOnBuildingEmptyIndexOnStartup ;
if ( _indexesToRebuild . Any ( ) )
{
foreach ( var indexer in _indexesToRebuild )
{
indexer . RebuildIndex ( ) ;
}
}
2013-02-14 23:26:29 +06:00
2015-05-08 19:13:58 +10:00
//Now ensure webapi is initialized after everything
GlobalConfiguration . Configuration . EnsureInitialized ( ) ;
2013-01-18 08:47:38 -01:00
return this ;
}
2014-02-26 04:15:14 +11:00
internal static void WrapViewEngines ( IList < IViewEngine > viewEngines )
{
if ( viewEngines = = null | | viewEngines . Count = = 0 ) return ;
2013-10-03 11:01:37 +02:00
2014-02-26 04:15:14 +11:00
var originalEngines = viewEngines . Select ( e = > e ) . ToArray ( ) ;
viewEngines . Clear ( ) ;
foreach ( var engine in originalEngines )
{
var wrappedEngine = engine is ProfilingViewEngine ? engine : new ProfilingViewEngine ( engine ) ;
viewEngines . Add ( wrappedEngine ) ;
}
}
2013-10-03 11:01:37 +02:00
2014-02-26 04:15:14 +11:00
/// <summary>
2013-07-02 17:47:20 +10:00
/// Creates the application cache based on the HttpRuntime cache
/// </summary>
2015-07-23 18:26:56 +02:00
protected override CacheHelper CreateApplicationCache ( )
2013-07-02 17:47:20 +10:00
{
2013-08-09 11:37:57 +10:00
//create a web-based cache helper
2015-07-23 18:26:56 +02:00
return new CacheHelper ( ) ;
2013-07-02 17:47:20 +10:00
}
2013-01-18 08:47:38 -01:00
/// <summary>
/// Creates the routes
/// </summary>
protected internal void CreateRoutes ( )
{
var umbracoPath = GlobalSettings . UmbracoMvcArea ;
2014-02-26 04:15:14 +11:00
2013-01-18 08:47:38 -01:00
//Create the front-end route
var defaultRoute = RouteTable . Routes . MapRoute (
"Umbraco_default" ,
2013-02-19 06:18:51 +06:00
umbracoPath + "/RenderMvc/{action}/{id}" ,
2013-01-18 08:47:38 -01:00
new { controller = "RenderMvc" , action = "Index" , id = UrlParameter . Optional }
) ;
defaultRoute . RouteHandler = new RenderRouteHandler ( ControllerBuilder . Current . GetControllerFactory ( ) ) ;
2014-02-26 04:15:14 +11:00
//register install routes
2014-03-05 22:42:51 +11:00
RouteTable . Routes . RegisterArea < UmbracoInstallArea > ( ) ;
2014-02-26 04:15:14 +11:00
2013-06-03 21:38:43 -10:00
//register all back office routes
2014-03-05 22:42:51 +11:00
RouteTable . Routes . RegisterArea < BackOfficeArea > ( ) ;
2013-01-18 08:47:38 -01:00
2013-05-29 20:25:29 -10:00
//plugin controllers must come first because the next route will catch many things
RoutePluginControllers ( ) ;
2013-06-03 21:38:43 -10:00
}
2014-03-05 22:42:51 +11:00
2013-02-26 03:45:39 +06:00
private void RoutePluginControllers ( )
{
var umbracoPath = GlobalSettings . UmbracoMvcArea ;
//we need to find the plugin controllers and route them
var pluginControllers =
SurfaceControllerResolver . Current . RegisteredSurfaceControllers . Concat (
UmbracoApiControllerResolver . Current . RegisteredUmbracoApiControllers ) . ToArray ( ) ;
2013-01-18 08:47:38 -01:00
2013-06-10 10:36:59 -02:00
//local controllers do not contain the attribute
2013-02-26 03:45:39 +06:00
var localControllers = pluginControllers . Where ( x = > PluginController . GetMetadata ( x ) . AreaName . IsNullOrWhiteSpace ( ) ) ;
foreach ( var s in localControllers )
2013-01-18 08:47:38 -01:00
{
2013-02-26 03:45:39 +06:00
if ( TypeHelper . IsTypeAssignableFrom < SurfaceController > ( s ) )
{
RouteLocalSurfaceController ( s , umbracoPath ) ;
}
else if ( TypeHelper . IsTypeAssignableFrom < UmbracoApiController > ( s ) )
{
RouteLocalApiController ( s , umbracoPath ) ;
}
2013-01-18 08:47:38 -01:00
}
//need to get the plugin controllers that are unique to each area (group by)
2013-02-26 03:45:39 +06:00
var pluginSurfaceControlleres = pluginControllers . Where ( x = > ! PluginController . GetMetadata ( x ) . AreaName . IsNullOrWhiteSpace ( ) ) ;
2013-01-18 08:47:38 -01:00
var groupedAreas = pluginSurfaceControlleres . GroupBy ( controller = > PluginController . GetMetadata ( controller ) . AreaName ) ;
//loop through each area defined amongst the controllers
foreach ( var g in groupedAreas )
{
//create an area for the controllers (this will throw an exception if all controllers are not in the same area)
var pluginControllerArea = new PluginControllerArea ( g . Select ( PluginController . GetMetadata ) ) ;
//register it
RouteTable . Routes . RegisterArea ( pluginControllerArea ) ;
}
}
2013-02-26 03:45:39 +06:00
private void RouteLocalApiController ( Type controller , string umbracoPath )
{
var meta = PluginController . GetMetadata ( controller ) ;
2014-01-15 13:17:38 +11:00
//url to match
var routePath = meta . IsBackOffice = = false
? umbracoPath + "/Api/" + meta . ControllerName + "/{action}/{id}"
: umbracoPath + "/BackOffice/Api/" + meta . ControllerName + "/{action}/{id}" ;
2014-02-26 04:15:14 +11:00
2013-02-26 03:45:39 +06:00
var route = RouteTable . Routes . MapHttpRoute (
string . Format ( "umbraco-{0}-{1}" , "api" , meta . ControllerName ) ,
2014-02-26 04:15:14 +11:00
routePath ,
2014-03-05 22:42:51 +11:00
new { controller = meta . ControllerName , id = UrlParameter . Optional } ,
new [ ] { meta . ControllerNamespace } ) ;
2013-02-26 03:45:39 +06:00
//web api routes don't set the data tokens object
if ( route . DataTokens = = null )
2014-02-26 04:15:14 +11:00
{
2013-02-26 03:45:39 +06:00
route . DataTokens = new RouteValueDictionary ( ) ;
}
route . DataTokens . Add ( "umbraco" , "api" ) ; //ensure the umbraco token is set
}
2015-07-23 20:04:40 +02:00
2013-02-26 03:45:39 +06:00
private void RouteLocalSurfaceController ( Type controller , string umbracoPath )
{
var meta = PluginController . GetMetadata ( controller ) ;
var route = RouteTable . Routes . MapRoute (
string . Format ( "umbraco-{0}-{1}" , "surface" , meta . ControllerName ) ,
umbracoPath + "/Surface/" + meta . ControllerName + "/{action}/{id}" , //url to match
2014-02-26 04:15:14 +11:00
new { controller = meta . ControllerName , action = "Index" , id = UrlParameter . Optional } ,
2013-02-26 03:45:39 +06:00
new [ ] { meta . ControllerNamespace } ) ; //look in this namespace to create the controller
route . DataTokens . Add ( "umbraco" , "surface" ) ; //ensure the umbraco token is set
2013-06-03 21:38:43 -10:00
route . DataTokens . Add ( "UseNamespaceFallback" , false ) ; //Don't look anywhere else except this namespace!
2013-02-26 03:45:39 +06:00
//make it use our custom/special SurfaceMvcHandler
route . RouteHandler = new SurfaceRouteHandler ( ) ;
}
2013-01-18 08:47:38 -01:00
/// <summary>
/// Initializes all web based and core resolves
/// </summary>
protected override void InitializeResolvers ( )
{
base . InitializeResolvers ( ) ;
2013-02-06 09:53:13 +06:00
2015-01-16 15:47:44 +11:00
XsltExtensionsResolver . Current = new XsltExtensionsResolver ( ServiceProvider , LoggerResolver . Current . Logger , ( ) = > PluginManager . Current . ResolveXsltExtensions ( ) ) ;
2013-08-29 17:14:34 +10:00
2013-04-28 16:09:24 -10:00
//set the default RenderMvcController
DefaultRenderMvcControllerResolver . Current = new DefaultRenderMvcControllerResolver ( typeof ( RenderMvcController ) ) ;
2015-07-15 17:27:01 +02:00
//Override the default server messenger, we need to check if the legacy dist calls is enabled, if that is the
// case, then we'll set the default messenger to be the old one, otherwise we'll set it to the db messenger
// which will always be on.
if ( UmbracoConfig . For . UmbracoSettings ( ) . DistributedCall . Enabled )
2013-02-12 03:46:27 +06:00
{
2015-07-15 17:27:01 +02:00
//set the legacy one by default - this maintains backwards compat
ServerMessengerResolver . Current . SetServerMessenger ( new BatchedWebServiceServerMessenger ( ( ) = >
2014-02-26 04:15:14 +11:00
{
2015-07-15 17:27:01 +02:00
//we should not proceed to change this if the app/database is not configured since there will
// be no user, plus we don't need to have server messages sent if this is the case.
if ( ApplicationContext . IsConfigured & & ApplicationContext . DatabaseContext . IsDatabaseConfigured )
2015-03-04 12:16:28 +01:00
{
2015-07-15 17:27:01 +02:00
//disable if they are not enabled
if ( UmbracoConfig . For . UmbracoSettings ( ) . DistributedCall . Enabled = = false )
{
return null ;
}
try
{
var user = ApplicationContext . Services . UserService . GetUserById ( UmbracoConfig . For . UmbracoSettings ( ) . DistributedCall . UserId ) ;
return new Tuple < string , string > ( user . Username , user . RawPasswordValue ) ;
}
catch ( Exception e )
{
LoggerResolver . Current . Logger . Error < WebBootManager > ( "An error occurred trying to set the IServerMessenger during application startup" , e ) ;
return null ;
}
2015-03-04 12:16:28 +01:00
}
2015-07-15 17:27:01 +02:00
LoggerResolver . Current . Logger . Warn < WebBootManager > ( "Could not initialize the DefaultServerMessenger, the application is not configured or the database is not configured" ) ;
return null ;
} ) ) ;
}
else
{
2015-07-24 18:07:20 +02:00
// NOTE: This is IMPORTANT! ... we don't want to rebuild any index that is already flagged to be re-indexed
// on startup based on our _indexesToRebuild variable and how Examine auto-rebuilds when indexes are empty
// this callback is used below for the DatabaseServerMessenger startup options
Action rebuildIndexes = ( ) = >
{
2015-07-24 18:52:04 +02:00
//If the developer has explicitly opted out of rebuilding indexes on startup then we
// should adhere to that and not do it, this means that if they are load balancing things will be
// out of sync if they are auto-scaling but there's not much we can do about that.
if ( ExamineSettings . Instance . RebuildOnAppStart = = false ) return ;
2015-07-24 18:07:20 +02:00
if ( _indexesToRebuild . Any ( ) )
{
var otherIndexes = ExamineManager . Instance . IndexProviderCollection . Except ( _indexesToRebuild ) ;
foreach ( var otherIndex in otherIndexes )
{
otherIndex . RebuildIndex ( ) ;
}
}
else
{
//rebuild them all
ExamineManager . Instance . RebuildIndex ( ) ;
}
} ;
2015-07-15 17:27:01 +02:00
ServerMessengerResolver . Current . SetServerMessenger ( new BatchedDatabaseServerMessenger (
ApplicationContext ,
true ,
2015-07-24 18:07:20 +02:00
//Default options for web including the required callbacks to build caches
2015-07-15 17:27:01 +02:00
new DatabaseServerMessengerOptions
{
//These callbacks will be executed if the server has not been synced
// (i.e. it is a new server or the lastsynced.txt file has been removed)
InitializingCallbacks = new Action [ ]
2013-03-16 01:37:05 +06:00
{
2015-07-15 17:27:01 +02:00
//rebuild the xml cache file if the server is not synced
( ) = > global :: umbraco . content . Instance . RefreshContentFromDatabase ( ) ,
//rebuild indexes if the server is not synced
// NOTE: This will rebuild ALL indexes including the members, if developers want to target specific
2015-07-24 18:07:20 +02:00
// indexes then they can adjust this logic themselves.
rebuildIndexes
2013-03-16 01:37:05 +06:00
}
2015-07-15 17:27:01 +02:00
} ) ) ;
}
2014-02-26 04:15:14 +11:00
2013-01-18 08:47:38 -01:00
SurfaceControllerResolver . Current = new SurfaceControllerResolver (
2015-01-16 15:47:44 +11:00
ServiceProvider , LoggerResolver . Current . Logger ,
2013-01-18 08:47:38 -01:00
PluginManager . Current . ResolveSurfaceControllers ( ) ) ;
2013-02-26 03:45:39 +06:00
UmbracoApiControllerResolver . Current = new UmbracoApiControllerResolver (
2015-01-16 15:47:44 +11:00
ServiceProvider , LoggerResolver . Current . Logger ,
2013-02-26 03:45:39 +06:00
PluginManager . Current . ResolveUmbracoApiControllers ( ) ) ;
2013-09-23 16:30:24 +02:00
// both TinyMceValueConverter (in Core) and RteMacroRenderingValueConverter (in Web) will be
// discovered when CoreBootManager configures the converters. We HAVE to remove one of them
// here because there cannot be two converters for one property editor - and we want the full
// RteMacroRenderingValueConverter that converts macros, etc. So remove TinyMceValueConverter.
2013-10-04 20:14:38 +02:00
// (the limited one, defined in Core, is there for tests)
2013-09-05 17:47:13 +02:00
PropertyValueConvertersResolver . Current . RemoveType < TinyMceValueConverter > ( ) ;
2013-10-04 20:14:38 +02:00
// same for other converters
PropertyValueConvertersResolver . Current . RemoveType < Core . PropertyEditors . ValueConverters . TextStringValueConverter > ( ) ;
2013-10-30 08:59:28 +11:00
PropertyValueConvertersResolver . Current . RemoveType < Core . PropertyEditors . ValueConverters . MarkdownEditorValueConverter > ( ) ;
2013-01-18 08:47:38 -01:00
2013-03-31 18:40:55 -02:00
PublishedCachesResolver . Current = new PublishedCachesResolver ( new PublishedCaches (
new PublishedCache . XmlPublishedCache . PublishedContentCache ( ) ,
2014-11-19 11:35:37 +11:00
new PublishedCache . XmlPublishedCache . PublishedMediaCache ( ApplicationContext ) ) ) ;
2013-01-18 08:47:38 -01:00
2014-06-27 13:34:15 +10:00
GlobalConfiguration . Configuration . Services . Replace ( typeof ( IHttpControllerSelector ) ,
new NamespaceHttpControllerSelector ( GlobalConfiguration . Configuration ) ) ;
2013-01-18 08:47:38 -01:00
FilteredControllerFactoriesResolver . Current = new FilteredControllerFactoriesResolver (
2015-01-16 15:47:44 +11:00
ServiceProvider , LoggerResolver . Current . Logger ,
2013-01-31 10:06:25 -01:00
// add all known factories, devs can then modify this list on application
// startup either by binding to events or in their own global.asax
2013-01-18 08:47:38 -01:00
new [ ]
2012-08-07 21:40:34 +06:00
{
typeof ( RenderControllerFactory )
} ) ;
2013-01-31 10:06:25 -01:00
UrlProviderResolver . Current = new UrlProviderResolver (
2015-01-16 15:47:44 +11:00
ServiceProvider , LoggerResolver . Current . Logger ,
2014-10-29 18:20:01 +10:00
//typeof(AliasUrlProvider), // not enabled by default
typeof ( DefaultUrlProvider ) ,
typeof ( CustomRouteUrlProvider )
2013-01-31 10:06:25 -01:00
) ;
2013-08-26 15:47:48 +02:00
ContentLastChanceFinderResolver . Current = new ContentLastChanceFinderResolver (
// handled by ContentLastChanceFinderByNotFoundHandlers for the time being
// soon as we get rid of INotFoundHandler support, we must enable this
//new ContentFinderByLegacy404()
// implement INotFoundHandler support... remove once we get rid of it
new ContentLastChanceFinderByNotFoundHandlers ( ) ) ;
2012-08-01 22:06:15 +06:00
2014-02-26 04:15:14 +11:00
ContentFinderResolver . Current = new ContentFinderResolver (
2015-01-16 15:47:44 +11:00
ServiceProvider , LoggerResolver . Current . Logger ,
2013-08-26 15:47:48 +02:00
// all built-in finders in the correct order, devs can then modify this list
// on application startup via an application event handler.
2014-02-26 04:15:14 +11:00
typeof ( ContentFinderByPageIdQuery ) ,
typeof ( ContentFinderByNiceUrl ) ,
typeof ( ContentFinderByIdPath ) ,
2013-08-26 15:47:48 +02:00
// these will be handled by ContentFinderByNotFoundHandlers so they can be enabled/disabled
// via the config file... soon as we get rid of INotFoundHandler support, we must enable
// them here.
//typeof (ContentFinderByNiceUrlAndTemplate),
//typeof (ContentFinderByProfile),
//typeof (ContentFinderByUrlAlias),
// implement INotFoundHandler support... remove once we get rid of it
2014-02-26 04:15:14 +11:00
typeof ( ContentFinderByNotFoundHandlers )
) ;
2012-08-04 06:20:06 +06:00
2013-02-19 06:37:25 -01:00
SiteDomainHelperResolver . Current = new SiteDomainHelperResolver ( new SiteDomainHelper ( ) ) ;
2013-03-31 18:40:55 -02:00
// ain't that a bit dirty?
PublishedCache . XmlPublishedCache . PublishedContentCache . UnitTesting = _isForTesting ;
2012-08-04 06:20:06 +06:00
2013-01-18 08:47:38 -01:00
ThumbnailProvidersResolver . Current = new ThumbnailProvidersResolver (
2015-01-16 15:47:44 +11:00
ServiceProvider , LoggerResolver . Current . Logger ,
2013-01-18 08:47:38 -01:00
PluginManager . Current . ResolveThumbnailProviders ( ) ) ;
2012-08-15 23:20:37 +06:00
2012-11-21 07:14:40 -01:00
ImageUrlProviderResolver . Current = new ImageUrlProviderResolver (
2015-01-16 15:47:44 +11:00
ServiceProvider , LoggerResolver . Current . Logger ,
2012-11-21 07:14:40 -01:00
PluginManager . Current . ResolveImageUrlProviders ( ) ) ;
2013-01-18 08:47:38 -01:00
CultureDictionaryFactoryResolver . Current = new CultureDictionaryFactoryResolver (
new DefaultCultureDictionaryFactory ( ) ) ;
}
2012-08-01 22:06:15 +06:00
2014-12-09 19:07:14 +11:00
private void OnInstanceOnBuildingEmptyIndexOnStartup ( object sender , BuildingEmptyIndexOnStartupEventArgs args )
{
//store the indexer that needs rebuilding because it's empty for when the boot process
// is complete and cancel this current event so the rebuild process doesn't start right now.
args . Cancel = true ;
_indexesToRebuild . Add ( args . Indexer ) ;
}
2013-01-18 08:47:38 -01:00
}
2012-08-01 22:06:15 +06:00
}