2012-08-01 22:06:15 +06:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
2012-12-15 08:41:46 +05:00
|
|
|
|
using Umbraco.Core.Configuration;
|
2012-08-01 22:06:15 +06:00
|
|
|
|
using Umbraco.Core.Logging;
|
2012-08-10 13:18:13 +06:00
|
|
|
|
using Umbraco.Core.ObjectResolution;
|
2012-12-09 09:01:00 +05:00
|
|
|
|
using Umbraco.Core.Persistence;
|
2012-12-29 18:53:13 -01:00
|
|
|
|
using Umbraco.Core.Persistence.Mappers;
|
2013-01-10 04:33:30 +03:00
|
|
|
|
using Umbraco.Core.Persistence.Migrations;
|
2013-01-18 12:00:29 -01:00
|
|
|
|
using Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix;
|
2013-02-28 14:54:42 -01:00
|
|
|
|
using Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixZeroOne;
|
2013-03-09 10:43:34 -01:00
|
|
|
|
using Umbraco.Core.Persistence.SqlSyntax;
|
2012-12-14 08:06:32 +05:00
|
|
|
|
using Umbraco.Core.Persistence.UnitOfWork;
|
2012-08-18 11:39:18 +06:00
|
|
|
|
using Umbraco.Core.PropertyEditors;
|
2012-12-14 08:06:32 +05:00
|
|
|
|
using Umbraco.Core.Publishing;
|
2013-01-16 13:31:04 -01:00
|
|
|
|
using Umbraco.Core.Macros;
|
2012-12-14 08:06:32 +05:00
|
|
|
|
using Umbraco.Core.Services;
|
2013-02-11 20:07:23 +06:00
|
|
|
|
using Umbraco.Core.Sync;
|
2013-02-07 13:30:50 -01:00
|
|
|
|
using Umbraco.Core.Strings;
|
2013-01-10 04:33:30 +03:00
|
|
|
|
using MigrationsVersionFourNineZero = Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionFourNineZero;
|
2012-08-01 22:06:15 +06:00
|
|
|
|
|
|
|
|
|
|
namespace Umbraco.Core
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// A bootstrapper for the Umbraco application which initializes all objects for the Core of the application
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <remarks>
|
|
|
|
|
|
/// This does not provide any startup functionality relating to web objects
|
|
|
|
|
|
/// </remarks>
|
2012-12-12 20:10:50 +05:00
|
|
|
|
public class CoreBootManager : IBootManager
|
2012-08-01 22:06:15 +06:00
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
private DisposableTimer _timer;
|
2012-08-07 21:40:34 +06:00
|
|
|
|
private bool _isInitialized = false;
|
|
|
|
|
|
private bool _isStarted = false;
|
|
|
|
|
|
private bool _isComplete = false;
|
2013-01-29 09:45:12 +06:00
|
|
|
|
private readonly UmbracoApplicationBase _umbracoApplication;
|
2012-08-14 12:03:34 +06:00
|
|
|
|
protected ApplicationContext ApplicationContext { get; private set; }
|
|
|
|
|
|
|
2013-01-29 09:45:12 +06:00
|
|
|
|
protected UmbracoApplicationBase UmbracoApplication
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return _umbracoApplication; }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public CoreBootManager(UmbracoApplicationBase umbracoApplication)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (umbracoApplication == null) throw new ArgumentNullException("umbracoApplication");
|
|
|
|
|
|
_umbracoApplication = umbracoApplication;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public virtual IBootManager Initialize()
|
2012-08-01 22:06:15 +06:00
|
|
|
|
{
|
2012-08-07 21:40:34 +06:00
|
|
|
|
if (_isInitialized)
|
|
|
|
|
|
throw new InvalidOperationException("The boot manager has already been initialized");
|
|
|
|
|
|
|
2012-08-01 22:06:15 +06:00
|
|
|
|
LogHelper.Info<CoreBootManager>("Umbraco application starting");
|
|
|
|
|
|
_timer = DisposableTimer.Start(x => LogHelper.Info<CoreBootManager>("Umbraco application startup complete" + " (took " + x + "ms)"));
|
|
|
|
|
|
|
2012-12-14 08:06:32 +05:00
|
|
|
|
//create database and service contexts for the app context
|
2012-12-15 08:41:46 +05:00
|
|
|
|
var dbFactory = new DefaultDatabaseFactory(GlobalSettings.UmbracoConnectionName);
|
2013-01-10 04:33:30 +03:00
|
|
|
|
Database.Mapper = new PetaPocoMapper();
|
2012-12-15 08:41:46 +05:00
|
|
|
|
var dbContext = new DatabaseContext(dbFactory);
|
|
|
|
|
|
var serviceContext = new ServiceContext(
|
|
|
|
|
|
new PetaPocoUnitOfWorkProvider(dbFactory),
|
|
|
|
|
|
new FileUnitOfWorkProvider(),
|
|
|
|
|
|
new PublishingStrategy());
|
2013-03-11 23:46:47 +06:00
|
|
|
|
|
|
|
|
|
|
CreateApplicationContext(dbContext, serviceContext);
|
2012-08-01 22:06:15 +06:00
|
|
|
|
|
2013-01-29 09:45:12 +06:00
|
|
|
|
InitializeApplicationEventsResolver();
|
|
|
|
|
|
|
2012-08-01 22:06:15 +06:00
|
|
|
|
InitializeResolvers();
|
2013-03-09 10:43:34 -01:00
|
|
|
|
|
|
|
|
|
|
//initialize the DatabaseContext
|
|
|
|
|
|
dbContext.Initialize();
|
|
|
|
|
|
|
2013-01-29 09:45:12 +06:00
|
|
|
|
//now we need to call the initialize methods
|
|
|
|
|
|
ApplicationEventsResolver.Current.ApplicationEventHandlers
|
|
|
|
|
|
.ForEach(x => x.OnApplicationInitialized(UmbracoApplication, ApplicationContext));
|
|
|
|
|
|
|
2012-08-07 21:40:34 +06:00
|
|
|
|
_isInitialized = true;
|
|
|
|
|
|
|
2012-08-01 22:06:15 +06:00
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2013-03-11 23:46:47 +06:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Creates and assigns the application context singleton
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="dbContext"></param>
|
|
|
|
|
|
/// <param name="serviceContext"></param>
|
|
|
|
|
|
protected virtual void CreateApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext)
|
|
|
|
|
|
{
|
|
|
|
|
|
//create the ApplicationContext
|
|
|
|
|
|
ApplicationContext = ApplicationContext.Current = new ApplicationContext(dbContext, serviceContext);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2013-01-29 09:45:12 +06:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Special method to initialize the ApplicationEventsResolver and any modifications required for it such
|
|
|
|
|
|
/// as adding custom types to the resolver.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
protected virtual void InitializeApplicationEventsResolver()
|
|
|
|
|
|
{
|
|
|
|
|
|
//find and initialize the application startup handlers, we need to initialize this resolver here because
|
|
|
|
|
|
//it is a special resolver where they need to be instantiated first before any other resolvers in order to bind to
|
|
|
|
|
|
//events and to call their events during bootup.
|
|
|
|
|
|
//ApplicationStartupHandler.RegisterHandlers();
|
|
|
|
|
|
//... and set the special flag to let us resolve before frozen resolution
|
|
|
|
|
|
ApplicationEventsResolver.Current = new ApplicationEventsResolver(
|
|
|
|
|
|
PluginManager.Current.ResolveApplicationStartupHandlers())
|
|
|
|
|
|
{
|
|
|
|
|
|
CanResolveBeforeFrozen = true
|
|
|
|
|
|
};
|
2013-02-06 09:53:13 +06:00
|
|
|
|
//add custom types here that are internal
|
2013-02-02 07:06:27 +06:00
|
|
|
|
ApplicationEventsResolver.Current.AddType<PublishedContentHelper>();
|
2013-01-29 09:45:12 +06:00
|
|
|
|
}
|
|
|
|
|
|
|
2012-08-01 22:06:15 +06:00
|
|
|
|
/// <summary>
|
2013-01-29 09:45:12 +06:00
|
|
|
|
/// Fires after initialization and calls the callback to allow for customizations to occur &
|
|
|
|
|
|
/// Ensure that the OnApplicationStarting methods of the IApplicationEvents are called
|
2012-08-01 22:06:15 +06:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="afterStartup"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public virtual IBootManager Startup(Action<ApplicationContext> afterStartup)
|
|
|
|
|
|
{
|
2012-08-07 21:40:34 +06:00
|
|
|
|
if (_isStarted)
|
|
|
|
|
|
throw new InvalidOperationException("The boot manager has already been initialized");
|
|
|
|
|
|
|
2013-01-29 09:45:12 +06:00
|
|
|
|
//call OnApplicationStarting of each application events handler
|
|
|
|
|
|
ApplicationEventsResolver.Current.ApplicationEventHandlers
|
|
|
|
|
|
.ForEach(x => x.OnApplicationStarting(UmbracoApplication, ApplicationContext));
|
|
|
|
|
|
|
2013-02-14 23:05:58 +06:00
|
|
|
|
if (afterStartup != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
afterStartup(ApplicationContext.Current);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2012-08-07 21:40:34 +06:00
|
|
|
|
_isStarted = true;
|
|
|
|
|
|
|
2012-08-01 22:06:15 +06:00
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Fires after startup and calls the callback once customizations are locked
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="afterComplete"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public virtual IBootManager Complete(Action<ApplicationContext> afterComplete)
|
|
|
|
|
|
{
|
2012-08-07 21:40:34 +06:00
|
|
|
|
if (_isComplete)
|
|
|
|
|
|
throw new InvalidOperationException("The boot manager has already been completed");
|
|
|
|
|
|
|
2013-03-11 23:46:47 +06:00
|
|
|
|
FreezeResolution();
|
2012-08-01 22:06:15 +06:00
|
|
|
|
|
|
|
|
|
|
//stop the timer and log the output
|
|
|
|
|
|
_timer.Dispose();
|
|
|
|
|
|
|
2013-01-29 09:45:12 +06:00
|
|
|
|
//call OnApplicationStarting of each application events handler
|
|
|
|
|
|
ApplicationEventsResolver.Current.ApplicationEventHandlers
|
|
|
|
|
|
.ForEach(x => x.OnApplicationStarted(UmbracoApplication, ApplicationContext));
|
|
|
|
|
|
|
2013-02-14 23:05:58 +06:00
|
|
|
|
//Now, startup all of our legacy startup handler
|
|
|
|
|
|
ApplicationEventsResolver.Current.InstantiateLegacyStartupHanlders();
|
|
|
|
|
|
|
|
|
|
|
|
if (afterComplete != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
afterComplete(ApplicationContext.Current);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2012-08-07 21:40:34 +06:00
|
|
|
|
_isComplete = true;
|
|
|
|
|
|
|
2013-01-29 09:45:12 +06:00
|
|
|
|
// we're ready to serve content!
|
|
|
|
|
|
ApplicationContext.IsReady = true;
|
|
|
|
|
|
|
2012-08-01 22:06:15 +06:00
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2013-03-12 00:21:10 +04:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Freeze resolution to not allow Resolvers to be modified
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
protected virtual void FreezeResolution()
|
|
|
|
|
|
{
|
|
|
|
|
|
Resolution.Freeze();
|
|
|
|
|
|
}
|
2013-03-12 00:40:37 +04:00
|
|
|
|
|
2012-08-01 22:06:15 +06:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Create the resolvers
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
protected virtual void InitializeResolvers()
|
|
|
|
|
|
{
|
2013-02-12 03:46:27 +06:00
|
|
|
|
//by default we'll use the standard configuration based sync
|
2013-02-11 20:07:23 +06:00
|
|
|
|
ServerRegistrarResolver.Current = new ServerRegistrarResolver(
|
2013-02-12 03:46:27 +06:00
|
|
|
|
new ConfigServerRegistrar());
|
|
|
|
|
|
|
|
|
|
|
|
//by default (outside of the web) we'll use the default server messenger without
|
|
|
|
|
|
//supplying a username/password, this will automatically disable distributed calls
|
|
|
|
|
|
// .. we'll override this in the WebBootManager
|
|
|
|
|
|
ServerMessengerResolver.Current = new ServerMessengerResolver(
|
|
|
|
|
|
new DefaultServerMessenger());
|
2013-02-11 20:07:23 +06:00
|
|
|
|
|
2012-12-10 02:58:23 +05:00
|
|
|
|
RepositoryResolver.Current = new RepositoryResolver(
|
|
|
|
|
|
new RepositoryFactory());
|
2012-12-09 09:01:00 +05:00
|
|
|
|
|
2013-03-09 10:43:34 -01:00
|
|
|
|
SqlSyntaxProvidersResolver.Current = new SqlSyntaxProvidersResolver(
|
2013-03-11 12:44:12 -01:00
|
|
|
|
new[] { typeof(MySqlSyntaxProvider), typeof(SqlCeSyntaxProvider), typeof(SqlServerSyntaxProvider) })
|
2013-03-09 10:43:34 -01:00
|
|
|
|
{
|
|
|
|
|
|
CanResolveBeforeFrozen = true
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2012-08-01 22:06:15 +06:00
|
|
|
|
CacheRefreshersResolver.Current = new CacheRefreshersResolver(
|
2013-01-23 18:40:40 +03:00
|
|
|
|
() => PluginManager.Current.ResolveCacheRefreshers());
|
2012-08-01 22:06:15 +06:00
|
|
|
|
|
|
|
|
|
|
DataTypesResolver.Current = new DataTypesResolver(
|
2013-01-23 18:40:40 +03:00
|
|
|
|
() => PluginManager.Current.ResolveDataTypes());
|
2012-08-01 22:46:13 +06:00
|
|
|
|
|
|
|
|
|
|
MacroFieldEditorsResolver.Current = new MacroFieldEditorsResolver(
|
2013-01-23 18:40:40 +03:00
|
|
|
|
() => PluginManager.Current.ResolveMacroRenderings());
|
2012-08-01 23:03:26 +06:00
|
|
|
|
|
|
|
|
|
|
PackageActionsResolver.Current = new PackageActionsResolver(
|
2013-01-23 18:40:40 +03:00
|
|
|
|
() => PluginManager.Current.ResolvePackageActions());
|
2012-08-01 23:30:37 +06:00
|
|
|
|
|
|
|
|
|
|
ActionsResolver.Current = new ActionsResolver(
|
2013-01-23 18:40:40 +03:00
|
|
|
|
() => PluginManager.Current.ResolveActions());
|
2012-08-18 11:39:18 +06:00
|
|
|
|
|
2012-10-30 09:25:28 -01:00
|
|
|
|
MacroPropertyTypeResolver.Current = new MacroPropertyTypeResolver(
|
|
|
|
|
|
PluginManager.Current.ResolveMacroPropertyTypes());
|
|
|
|
|
|
|
2013-02-13 03:29:32 +06:00
|
|
|
|
//the database migration objects
|
|
|
|
|
|
MigrationResolver.Current = new MigrationResolver(
|
|
|
|
|
|
() => PluginManager.Current.ResolveMigrationTypes());
|
2013-01-21 10:01:14 -01:00
|
|
|
|
|
2013-01-18 12:05:00 -01:00
|
|
|
|
|
|
|
|
|
|
|
2012-08-18 11:39:18 +06:00
|
|
|
|
PropertyEditorValueConvertersResolver.Current = new PropertyEditorValueConvertersResolver(
|
2012-11-05 06:14:44 +06:00
|
|
|
|
PluginManager.Current.ResolvePropertyEditorValueConverters());
|
|
|
|
|
|
//add the internal ones, these are not public currently so need to add them manually
|
|
|
|
|
|
PropertyEditorValueConvertersResolver.Current.AddType<DatePickerPropertyEditorValueConverter>();
|
|
|
|
|
|
PropertyEditorValueConvertersResolver.Current.AddType<TinyMcePropertyEditorValueConverter>();
|
|
|
|
|
|
PropertyEditorValueConvertersResolver.Current.AddType<YesNoPropertyEditorValueConverter>();
|
2013-02-07 13:30:50 -01:00
|
|
|
|
|
|
|
|
|
|
ShortStringHelperResolver.Current = new ShortStringHelperResolver(
|
|
|
|
|
|
new LegacyShortStringHelper());
|
2013-02-18 08:31:00 -01:00
|
|
|
|
UrlSegmentProviderResolver.Current = new UrlSegmentProviderResolver(
|
|
|
|
|
|
typeof (DefaultUrlSegmentProvider));
|
2013-02-07 13:30:50 -01:00
|
|
|
|
}
|
2012-08-01 22:06:15 +06:00
|
|
|
|
}
|
|
|
|
|
|
}
|