diff --git a/src/Umbraco.Core/ApplicationEventHandler.cs b/src/Umbraco.Core/ApplicationEventHandler.cs
index a725a08a8e..8d97baac95 100644
--- a/src/Umbraco.Core/ApplicationEventHandler.cs
+++ b/src/Umbraco.Core/ApplicationEventHandler.cs
@@ -74,7 +74,7 @@ namespace Umbraco.Core
///
private bool ShouldExecute(ApplicationContext applicationContext)
{
- if (applicationContext.IsConfigured && applicationContext.DatabaseContext.CanConnect)
+ if (applicationContext.IsConfigured && applicationContext.DatabaseContext.IsDatabaseConfigured)
{
return true;
}
@@ -84,7 +84,7 @@ namespace Umbraco.Core
return true;
}
- if (!applicationContext.DatabaseContext.CanConnect && ExecuteWhenDatabaseNotConfigured)
+ if (!applicationContext.DatabaseContext.IsDatabaseConfigured && ExecuteWhenDatabaseNotConfigured)
{
return true;
}
diff --git a/src/Umbraco.Core/CoreBootManager.cs b/src/Umbraco.Core/CoreBootManager.cs
index f5dbdcf957..c5d3e2a4c7 100644
--- a/src/Umbraco.Core/CoreBootManager.cs
+++ b/src/Umbraco.Core/CoreBootManager.cs
@@ -2,10 +2,12 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Threading;
using System.Web;
using AutoMapper;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
+using Umbraco.Core.Exceptions;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.Mapping;
@@ -261,6 +263,9 @@ namespace Umbraco.Core
FreezeResolution();
+ //Here we need to make sure the db can be connected to
+ EnsureDatabaseConnection();
+
using (DisposableTimer.DebugDuration(
() => string.Format("Executing {0} IApplicationEventHandler.OnApplicationStarted", ApplicationEventsResolver.Current.ApplicationEventHandlers.Count()),
() => "Finished executing IApplicationEventHandler.OnApplicationStarted"))
@@ -299,6 +304,32 @@ namespace Umbraco.Core
return this;
}
+ ///
+ /// We cannot continue if the db cannot be connected to
+ ///
+ private void EnsureDatabaseConnection()
+ {
+ if (ApplicationContext.IsConfigured == false) return;
+ if (ApplicationContext.DatabaseContext.IsDatabaseConfigured == false) return;
+
+ var currentTry = 0;
+ while (currentTry < 5)
+ {
+ if (ApplicationContext.DatabaseContext.CanConnect)
+ break;
+
+ //wait and retry
+ Thread.Sleep(1000);
+ currentTry++;
+ }
+
+ if (currentTry == 5)
+ {
+ throw new UmbracoStartupFailedException("Umbraco cannot start. A connection string is configured but the Umbraco cannot connect to the database.");
+ }
+
+ }
+
///
/// Freeze resolution to not allow Resolvers to be modified
///
diff --git a/src/Umbraco.Core/DatabaseContext.cs b/src/Umbraco.Core/DatabaseContext.cs
index fad96b849d..dfaebb0315 100644
--- a/src/Umbraco.Core/DatabaseContext.cs
+++ b/src/Umbraco.Core/DatabaseContext.cs
@@ -26,8 +26,6 @@ namespace Umbraco.Core
{
private readonly IDatabaseFactory _factory;
private bool _configured;
- private bool _canConnect;
- private volatile bool _connectCheck = false;
private readonly object _locker = new object();
private string _connectionString;
private string _providerName;
@@ -67,21 +65,9 @@ namespace Umbraco.Core
get
{
if (IsDatabaseConfigured == false) return false;
-
- //double check lock so that it is only checked once and is fast
- if (_connectCheck == false)
- {
- lock (_locker)
- {
- if (_canConnect == false)
- {
- _canConnect = DbConnectionExtensions.IsConnectionAvailable(ConnectionString, DatabaseProvider);
- _connectCheck = true;
- }
- }
- }
-
- return _canConnect;
+ var canConnect = DbConnectionExtensions.IsConnectionAvailable(ConnectionString, DatabaseProvider);
+ LogHelper.Info("CanConnect = " + canConnect);
+ return canConnect;
}
}
diff --git a/src/Umbraco.Core/Exceptions/UmbracoStartupFailedException.cs b/src/Umbraco.Core/Exceptions/UmbracoStartupFailedException.cs
new file mode 100644
index 0000000000..d27d38de9a
--- /dev/null
+++ b/src/Umbraco.Core/Exceptions/UmbracoStartupFailedException.cs
@@ -0,0 +1,18 @@
+using System;
+
+namespace Umbraco.Core.Exceptions
+{
+ ///
+ /// An exception that is thrown if the umbraco application cannnot boot
+ ///
+ public class UmbracoStartupFailedException : Exception
+ {
+ ///
+ /// Initializes a new instance of the class with a specified error message.
+ ///
+ /// The message that describes the error.
+ public UmbracoStartupFailedException(string message) : base(message)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/TypeFinder.cs b/src/Umbraco.Core/TypeFinder.cs
index 962f0e3d91..abaf5ae5e0 100644
--- a/src/Umbraco.Core/TypeFinder.cs
+++ b/src/Umbraco.Core/TypeFinder.cs
@@ -700,7 +700,11 @@ namespace Umbraco.Core
#endregion
- public static Type GetTypeByName(string typeName)
+ //TODO: This isn't very elegant, and will have issues since the AppDomain.CurrentDomain
+ // doesn't actualy load in all assemblies, only the types that have been referenced so far.
+ // However, in a web context, the BuildManager will have executed which will force all assemblies
+ // to be loaded so it's fine for now.
+ internal static Type GetTypeByName(string typeName)
{
var type = Type.GetType(typeName);
if (type != null) return type;
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index 67ce55b8f1..4e155e1b3d 100644
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -312,6 +312,7 @@
+