diff --git a/src/Umbraco.Core/ApplicationContext.cs b/src/Umbraco.Core/ApplicationContext.cs
index 503b7e7dd0..0e497531f1 100644
--- a/src/Umbraco.Core/ApplicationContext.cs
+++ b/src/Umbraco.Core/ApplicationContext.cs
@@ -44,32 +44,6 @@ namespace Umbraco.Core
Init();
}
- ///
- /// Constructor
- ///
- ///
- ///
- ///
- [Obsolete("Use the other constructor specifying a ProfilingLogger instead")]
- public ApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext, CacheHelper cache)
- : this(dbContext, serviceContext, cache,
- new ProfilingLogger(LoggerResolver.Current.Logger, ProfilerResolver.Current.Profiler))
- {
- }
-
- ///
- /// Creates a basic app context
- ///
- ///
- [Obsolete("Use the other constructor specifying a ProfilingLogger instead")]
- public ApplicationContext(CacheHelper cache)
- {
- if (cache == null) throw new ArgumentNullException("cache");
- ApplicationCache = cache;
- ProfilingLogger = new ProfilingLogger(LoggerResolver.Current.Logger, ProfilerResolver.Current.Profiler);
- Init();
- }
-
///
/// Creates a basic app context
///
@@ -106,33 +80,6 @@ namespace Umbraco.Core
return Current;
}
- ///
- /// A method used to create and ensure that a global ApplicationContext singleton is created.
- ///
- ///
- ///
- /// If set to true will replace the current singleton instance - This should only be used for unit tests or on app
- /// startup if for some reason the boot manager is not the umbraco boot manager.
- ///
- ///
- ///
- ///
- ///
- /// This is NOT thread safe
- ///
- [Obsolete("Use the other method specifying an ProfilingLogger instead")]
- public static ApplicationContext EnsureContext(DatabaseContext dbContext, ServiceContext serviceContext, CacheHelper cache, bool replaceContext)
- {
- if (Current != null)
- {
- if (!replaceContext)
- return Current;
- }
- var ctx = new ApplicationContext(dbContext, serviceContext, cache);
- Current = ctx;
- return Current;
- }
-
///
/// A method used to create and ensure that a global ApplicationContext singleton is created.
///
diff --git a/src/Umbraco.Core/CoreBootManager.cs b/src/Umbraco.Core/CoreBootManager.cs
index c56b02d74e..5a56e8e846 100644
--- a/src/Umbraco.Core/CoreBootManager.cs
+++ b/src/Umbraco.Core/CoreBootManager.cs
@@ -48,7 +48,7 @@ namespace Umbraco.Core
protected ProfilingLogger ProfilingLogger { get; private set; }
private DisposableTimer _timer;
protected PluginManager PluginManager { get; private set; }
- private CacheHelper _cacheHelper;
+
private bool _isInitialized = false;
private bool _isStarted = false;
@@ -88,16 +88,28 @@ namespace Umbraco.Core
if (_isInitialized)
throw new InvalidOperationException("The boot manager has already been initialized");
+ //Create logger/profiler, and their resolvers, these are special resolvers that can be resolved before frozen so we can start logging
+ LoggerResolver.Current = new LoggerResolver(_umbracoApplication.Logger) { CanResolveBeforeFrozen = true };
+ var profiler = CreateProfiler();
+ ProfilerResolver.Current = new ProfilerResolver(profiler) { CanResolveBeforeFrozen = true };
+ ProfilingLogger = new ProfilingLogger(_umbracoApplication.Logger, profiler);
+
ProfilingLogger = ProfilingLogger?? new ProfilingLogger(LoggerResolver.Current.Logger, ProfilerResolver.Current.Profiler);
+
+ ApplicationCache = CreateApplicationCache();
_timer = ProfilingLogger.TraceDuration(
string.Format("Umbraco {0} application starting on {1}", UmbracoVersion.GetSemanticVersion().ToSemanticString(), NetworkHelper.MachineName),
"Umbraco application startup complete");
- _cacheHelper = CreateApplicationCache();
- ServiceProvider = new ActivatorServiceProvider();
- PluginManager.Current = PluginManager = new PluginManager(ServiceProvider, _cacheHelper.RuntimeCache, ProfilingLogger, true);
- ApplicationCache = CreateApplicationCache();
+ ServiceProvider = new ActivatorServiceProvider();
+
+ //create the plugin manager
+ //TODO: this is currently a singleton but it would be better if it weren't. Unfortunately the only way to get
+ // rid of this singleton would be to put it into IoC and then use the ServiceLocator pattern.
+ PluginManager.Current = PluginManager = new PluginManager(ServiceProvider, ApplicationCache.RuntimeCache, ProfilingLogger, true);
+
+ //build up core IoC servoces
ConfigureCoreServices(Container);
//set the singleton resolved from the core container
@@ -117,14 +129,24 @@ namespace Umbraco.Core
_appStartupEvtContainer.RegisterCollection(PluginManager.ResolveApplicationStartupHandlers());
//build up standard IoC services
- ConfigureServices(Container);
+ ConfigureApplicationServices(Container);
InitializeResolvers();
InitializeModelMappers();
//now we need to call the initialize methods
- //TODO: Make sure to try/catch the OnApplicationInitialized!!
- Parallel.ForEach(_appStartupEvtContainer.GetAllInstances(), x => x.OnApplicationInitialized(UmbracoApplication, ApplicationContext));
+ Parallel.ForEach(_appStartupEvtContainer.GetAllInstances(), x =>
+ {
+ try
+ {
+ x.OnApplicationInitialized(UmbracoApplication, ApplicationContext);
+ }
+ catch (Exception ex)
+ {
+ ProfilingLogger.Logger.Error("An error occurred running OnApplicationInitialized for handler " + x.GetType(), ex);
+ throw;
+ }
+ });
_isInitialized = true;
@@ -134,20 +156,19 @@ namespace Umbraco.Core
///
/// Build the core container which contains all core things requird to build an app context
///
- private void ConfigureCoreServices(ServiceContainer container)
+ internal virtual void ConfigureCoreServices(ServiceContainer container)
{
container.Register(factory => container);
container.Register(factory => _umbracoApplication.Logger, new PerContainerLifetime());
container.Register(factory => ProfilingLogger.Profiler, new PerContainerLifetime());
container.Register(factory => ProfilingLogger, new PerContainerLifetime());
- var settings = UmbracoConfig.For.UmbracoSettings();
- container.Register(factory => settings);
- container.Register(factory => settings.Content);
- container.Register(factory => settings.RequestHandler);
+ container.Register(factory => UmbracoConfig.For.UmbracoSettings());
+ container.Register(factory => factory.GetInstance().Content);
+ container.Register(factory => factory.GetInstance().RequestHandler);
//TODO: Add the other config areas...
- container.Register(factory => _cacheHelper, new PerContainerLifetime());
- container.Register(factory => _cacheHelper.RuntimeCache, new PerContainerLifetime());
+ container.Register(factory => ApplicationCache, new PerContainerLifetime());
+ container.Register(factory => ApplicationCache.RuntimeCache, new PerContainerLifetime());
container.Register();
container.Register(factory => PluginManager, new PerContainerLifetime());
container.Register(factory => new DefaultDatabaseFactory(GlobalSettings.UmbracoConnectionName, factory.GetInstance()));
@@ -185,7 +206,7 @@ namespace Umbraco.Core
/// Called to customize the IoC container
///
///
- internal virtual void ConfigureServices(ServiceContainer container)
+ internal virtual void ConfigureApplicationServices(ServiceContainer container)
{
}
@@ -270,9 +291,19 @@ namespace Umbraco.Core
if (_isStarted)
throw new InvalidOperationException("The boot manager has already been initialized");
- //TODO: Make sure to try/catch the OnApplicationInitialized!!
//call OnApplicationStarting of each application events handler
- Parallel.ForEach(_appStartupEvtContainer.GetAllInstances(), x => x.OnApplicationStarting(UmbracoApplication, ApplicationContext));
+ Parallel.ForEach(_appStartupEvtContainer.GetAllInstances(), x =>
+ {
+ try
+ {
+ x.OnApplicationStarting(UmbracoApplication, ApplicationContext);
+ }
+ catch (Exception ex)
+ {
+ ProfilingLogger.Logger.Error("An error occurred running OnApplicationStarting for handler " + x.GetType(), ex);
+ throw;
+ }
+ });
if (afterStartup != null)
{
@@ -307,9 +338,18 @@ namespace Umbraco.Core
//call OnApplicationStarting of each application events handler
- //TODO: Make sure to try/catch the OnApplicationInitialized!!
- Parallel.ForEach(_appStartupEvtContainer.GetAllInstances(), x => x.OnApplicationStarted(UmbracoApplication, ApplicationContext));
-
+ Parallel.ForEach(_appStartupEvtContainer.GetAllInstances(), x =>
+ {
+ try
+ {
+ x.OnApplicationStarted(UmbracoApplication, ApplicationContext);
+ }
+ catch (Exception ex)
+ {
+ ProfilingLogger.Logger.Error("An error occurred running OnApplicationStarted for handler " + x.GetType(), ex);
+ throw;
+ }
+ });
//end the current scope which was created to intantiate all of the startup handlers
_appStartupEvtContainer.EndCurrentScope();
@@ -372,8 +412,9 @@ namespace Umbraco.Core
///
protected virtual void InitializeResolvers()
{
- var manifestParser = new ManifestParser(ProfilingLogger.Logger, new DirectoryInfo(IOHelper.MapPath("~/App_Plugins")), _cacheHelper.RuntimeCache);
- var manifestBuilder = new ManifestBuilder(_cacheHelper.RuntimeCache, manifestParser);
+
+ var manifestParser = new ManifestParser(ProfilingLogger.Logger, new DirectoryInfo(IOHelper.MapPath("~/App_Plugins")), ApplicationCache.RuntimeCache);
+ var manifestBuilder = new ManifestBuilder(ApplicationCache.RuntimeCache, manifestParser);
PropertyEditorResolver.Current = new PropertyEditorResolver(
Container, ProfilingLogger.Logger, () => PluginManager.ResolvePropertyEditors(),
diff --git a/src/Umbraco.Tests/BootManagers/CoreBootManagerTests.cs b/src/Umbraco.Tests/BootManagers/CoreBootManagerTests.cs
index 12e5f8de6a..847560af71 100644
--- a/src/Umbraco.Tests/BootManagers/CoreBootManagerTests.cs
+++ b/src/Umbraco.Tests/BootManagers/CoreBootManagerTests.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
+using LightInject;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
@@ -12,6 +13,7 @@ using Umbraco.Core.ObjectResolution;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Tests.TestHelpers;
using umbraco.interfaces;
+using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Persistence;
using Umbraco.Core.Profiling;
using Umbraco.Core.Services;
@@ -21,23 +23,12 @@ namespace Umbraco.Tests.BootManagers
[TestFixture]
public class CoreBootManagerTests : BaseUmbracoConfigurationTest
{
-
- private TestApp _testApp;
-
- [SetUp]
- public override void Initialize()
- {
- base.Initialize();
- _testApp = new TestApp();
- }
-
[TearDown]
public override void TearDown()
{
base.TearDown();
-
- _testApp = null;
ResolverCollection.ResetAll();
+ TestApplicationEventHandler.Reset();
}
@@ -50,6 +41,16 @@ namespace Umbraco.Tests.BootManagers
{
return new TestBootManager(this, new ProfilingLogger(Mock.Of(), Mock.Of()));
}
+
+ private ILogger _logger;
+
+ ///
+ /// Returns the logger instance for the application - this will be used throughout the entire app
+ ///
+ public override ILogger Logger
+ {
+ get { return _logger ?? (_logger = Mock.Of()); }
+ }
}
///
@@ -61,16 +62,35 @@ namespace Umbraco.Tests.BootManagers
: base(umbracoApplication, logger)
{
}
+
+ internal override void ConfigureCoreServices(ServiceContainer container)
+ {
+ base.ConfigureCoreServices(container);
+ container.Register(factory => SettingsForTests.GetDefault());
+ container.Register(factory => new DatabaseContext(
+ factory.GetInstance(),
+ factory.GetInstance(),
+ factory.GetInstance()), new PerContainerLifetime());
+ }
}
///
/// test event handler
///
- public class TestApplicationEventHandler : IApplicationEventHandler
+ public class TestApplicationEventHandler : DisposableObject, IApplicationEventHandler
{
+ public static void Reset()
+ {
+ Initialized = false;
+ Starting = false;
+ Started = false;
+ Disposed = false;
+ }
+
public static bool Initialized = false;
public static bool Starting = false;
public static bool Started = false;
+ public static bool Disposed = false;
public void OnApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
@@ -86,20 +106,39 @@ namespace Umbraco.Tests.BootManagers
{
Started = true;
}
+
+ protected override void DisposeResources()
+ {
+ Disposed = true;
+ }
+ }
+
+ [Test]
+ public void Disposes_App_Startup_Handlers_After_Startup()
+ {
+ using (var app = new TestApp())
+ {
+ app.StartApplication(app, new EventArgs());
+
+ Assert.IsTrue(TestApplicationEventHandler.Disposed);
+ }
}
[Test]
public void Handle_IApplicationEventHandler_Objects_Outside_Web_Context()
{
- _testApp.StartApplication(_testApp, new EventArgs());
+ using (var app = new TestApp())
+ {
+ app.StartApplication(app, new EventArgs());
- Assert.IsTrue(TestApplicationEventHandler.Initialized);
- Assert.IsTrue(TestApplicationEventHandler.Starting);
- Assert.IsTrue(TestApplicationEventHandler.Started);
+ Assert.IsTrue(TestApplicationEventHandler.Initialized);
+ Assert.IsTrue(TestApplicationEventHandler.Starting);
+ Assert.IsTrue(TestApplicationEventHandler.Started);
+ }
}
[Test]
- public void Raises_Events()
+ public void Raises_Starting_Events()
{
using (var app = new TestApp())
{
@@ -119,13 +158,11 @@ namespace Umbraco.Tests.BootManagers
app.ApplicationStarting += starting;
app.ApplicationStarted += started;
- _testApp.StartApplication(_testApp, new EventArgs());
+ app.StartApplication(app, new EventArgs());
app.ApplicationStarting -= starting;
app.ApplicationStarting -= started;
}
-
-
}
}
diff --git a/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs b/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs
index ae939778cb..3d408b1222 100644
--- a/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs
+++ b/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs
@@ -21,27 +21,6 @@ namespace Umbraco.Tests.Cache.PublishedCache
private ContextualPublishedContentCache _cache;
private XmlDocument _xml;
- private string GetLegacyXml()
- {
- return @"
-
-]>
-
-
-
-
-
-
-
-
-
-
-
-
-";
- }
-
private string GetXml()
{
return @"(), () => PluginManager.Current.ResolveAssignedMapperTypes()));
- }
- }
-
protected virtual ISqlSyntaxProvider SqlSyntax
{
get { return new SqlCeSyntaxProvider(); }
@@ -118,12 +108,12 @@ namespace Umbraco.Tests.TestHelpers
new DatabaseContext(dbFactory, Logger, SqlSyntax, "System.Data.SqlServerCe.4.0"),
//assign the service context
new ServiceContext(
- repositoryFactory,
- new PetaPocoUnitOfWorkProvider(dbFactory),
- new FileUnitOfWorkProvider(),
- new PublishingStrategy(evtMsgs, Logger),
- cacheHelper,
- Logger,
+ repositoryFactory,
+ new PetaPocoUnitOfWorkProvider(dbFactory),
+ new FileUnitOfWorkProvider(),
+ new PublishingStrategy(evtMsgs, Logger),
+ cacheHelper,
+ Logger,
evtMsgs,
Enumerable.Empty()),
cacheHelper,
@@ -132,7 +122,7 @@ namespace Umbraco.Tests.TestHelpers
IsReady = true
};
- base.Initialize();
+ ApplicationContext.Current = _appContext;
using (ProfilingLogger.TraceDuration("init"))
{
@@ -143,8 +133,8 @@ namespace Umbraco.Tests.TestHelpers
InitializeDatabase();
//ensure the configuration matches the current version for tests
- SettingsForTests.ConfigurationStatus = UmbracoVersion.GetSemanticVersion().ToSemanticString();
- }
+ SettingsForTests.ConfigurationStatus = UmbracoVersion.Current.ToString(3);
+ }
}
///
diff --git a/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs b/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs
index 4fae7a0564..c1a2f2b930 100644
--- a/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs
+++ b/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs
@@ -109,6 +109,16 @@ namespace Umbraco.Tests.TestHelpers
private static readonly object Locker = new object();
+ private MappingResolver _mappingResolver;
+ protected IMappingResolver MappingResolver
+ {
+ get
+ {
+ return _mappingResolver ??
+ (_mappingResolver = new MappingResolver(Container, Mock.Of(), () => PluginManager.Current.ResolveAssignedMapperTypes()));
+ }
+ }
+
private static void InitializeLegacyMappingsForCoreEditors()
{
lock (Locker)
@@ -181,7 +191,7 @@ namespace Umbraco.Tests.TestHelpers
{
var sqlSyntax = new SqlCeSyntaxProvider();
- var repoFactory = new RepositoryFactory(CacheHelper.CreateDisabledCacheHelper(), Logger, sqlSyntax, SettingsForTests.GenerateMockSettings(), Mock.Of());
+ var repoFactory = new RepositoryFactory(CacheHelper.CreateDisabledCacheHelper(), Logger, sqlSyntax, SettingsForTests.GenerateMockSettings(), MappingResolver);
var evtMsgs = new TransientMessagesFactory();
ApplicationContext.Current = new ApplicationContext(
diff --git a/src/Umbraco.Web/WebBootManager.cs b/src/Umbraco.Web/WebBootManager.cs
index d1c5177652..3d2dbcfb7e 100644
--- a/src/Umbraco.Web/WebBootManager.cs
+++ b/src/Umbraco.Web/WebBootManager.cs
@@ -308,16 +308,24 @@ namespace Umbraco.Web
}
///
- /// Called to customize the IoC container
+ /// Build the core container which contains all core things requird to build an app context
///
- ///
- internal override void ConfigureServices(ServiceContainer container)
+ internal override void ConfigureCoreServices(ServiceContainer container)
{
- base.ConfigureServices(container);
+ base.ConfigureCoreServices(container);
//Replace services:
container.Register();
+ }
+ ///
+ /// Called to customize the IoC container
+ ///
+ ///
+ internal override void ConfigureApplicationServices(ServiceContainer container)
+ {
+ base.ConfigureApplicationServices(container);
+
//IoC setup for LightInject for mvc/webapi
Container.EnableMvc();
Container.RegisterMvcControllers(PluginManager);