From 71026d6d15ef68e6159ddcb81011a2a143cb2fad Mon Sep 17 00:00:00 2001 From: Aaron Powell Date: Mon, 19 Nov 2018 21:23:08 +1100 Subject: [PATCH 1/5] Fixes 3713 Moved the UmbracoApplicationBase from Core to Web Moved the WebProfiler from Core to Web Removed UmbracoApplicationBase from the CoreRuntime, it's still in the WebRuntime (and registered there in DI) --- src/Umbraco.Core/Runtime/CoreRuntime.cs | 10 +--------- src/Umbraco.Core/Umbraco.Core.csproj | 4 ---- src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs | 8 ++++++-- src/Umbraco.Tests/Views/textpage.cshtml | 4 ++++ src/Umbraco.Tests/Views/textpage1.cshtml | 4 ++++ .../Logging/WebProfiler.cs | 4 +++- .../Logging/WebProfilerComponent.cs | 4 +++- .../Logging/WebProfilerProvider.cs | 2 +- src/Umbraco.Web/Runtime/WebRuntime.cs | 13 ++++++++++--- src/Umbraco.Web/Umbraco.Web.csproj | 4 ++++ .../UmbracoApplicationBase.cs | 3 ++- 11 files changed, 38 insertions(+), 22 deletions(-) mode change 100644 => 100755 src/Umbraco.Core/Runtime/CoreRuntime.cs mode change 100644 => 100755 src/Umbraco.Core/Umbraco.Core.csproj mode change 100644 => 100755 src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs create mode 100755 src/Umbraco.Tests/Views/textpage.cshtml create mode 100755 src/Umbraco.Tests/Views/textpage1.cshtml rename src/{Umbraco.Core => Umbraco.Web}/Logging/WebProfiler.cs (97%) mode change 100644 => 100755 rename src/{Umbraco.Core => Umbraco.Web}/Logging/WebProfilerComponent.cs (96%) mode change 100644 => 100755 rename src/{Umbraco.Core => Umbraco.Web}/Logging/WebProfilerProvider.cs (99%) mode change 100644 => 100755 mode change 100644 => 100755 src/Umbraco.Web/Runtime/WebRuntime.cs mode change 100644 => 100755 src/Umbraco.Web/Umbraco.Web.csproj rename src/{Umbraco.Core => Umbraco.Web}/UmbracoApplicationBase.cs (99%) mode change 100644 => 100755 diff --git a/src/Umbraco.Core/Runtime/CoreRuntime.cs b/src/Umbraco.Core/Runtime/CoreRuntime.cs old mode 100644 new mode 100755 index a8cf18cd23..3df69392ca --- a/src/Umbraco.Core/Runtime/CoreRuntime.cs +++ b/src/Umbraco.Core/Runtime/CoreRuntime.cs @@ -29,27 +29,19 @@ namespace Umbraco.Core.Runtime /// should be possible to use this runtime in console apps. public class CoreRuntime : IRuntime { - private readonly UmbracoApplicationBase _app; private BootLoader _bootLoader; private RuntimeState _state; /// /// Initializes a new instance of the class. /// - /// The Umbraco HttpApplication. - public CoreRuntime(UmbracoApplicationBase umbracoApplication) + public CoreRuntime() { - _app = umbracoApplication ?? throw new ArgumentNullException(nameof(umbracoApplication)); } /// public virtual void Boot(ServiceContainer container) { - // some components may want to initialize with the UmbracoApplicationBase - // well, they should not - we should not do this - // TODO remove this eventually. - container.RegisterInstance(_app); - Compose(container); // prepare essential stuff diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj old mode 100644 new mode 100755 index 2bfa52a80a..cc82f977d1 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -602,9 +602,6 @@ - - - @@ -1455,7 +1452,6 @@ - diff --git a/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs b/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs old mode 100644 new mode 100755 index 770dead600..b3a96021b1 --- a/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs +++ b/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs @@ -14,6 +14,7 @@ using Umbraco.Core.Runtime; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.TestHelpers.Stubs; using Umbraco.Examine; +using Umbraco.Web; namespace Umbraco.Tests.Runtimes { @@ -80,8 +81,10 @@ namespace Umbraco.Tests.Runtimes public class TestRuntime : CoreRuntime { public TestRuntime(UmbracoApplicationBase umbracoApplication) - : base(umbracoApplication) - { } + : base() + { + _umbracoApplication = umbracoApplication; + } public override void Compose(ServiceContainer container) { @@ -115,6 +118,7 @@ namespace Umbraco.Tests.Runtimes } private MainDom _mainDom; + private readonly UmbracoApplicationBase _umbracoApplication; public override void Boot(ServiceContainer container) { diff --git a/src/Umbraco.Tests/Views/textpage.cshtml b/src/Umbraco.Tests/Views/textpage.cshtml new file mode 100755 index 0000000000..d7b4dce307 --- /dev/null +++ b/src/Umbraco.Tests/Views/textpage.cshtml @@ -0,0 +1,4 @@ +@inherits Umbraco.Web.Mvc.UmbracoViewPage +@{ + Layout = null; +} \ No newline at end of file diff --git a/src/Umbraco.Tests/Views/textpage1.cshtml b/src/Umbraco.Tests/Views/textpage1.cshtml new file mode 100755 index 0000000000..d7b4dce307 --- /dev/null +++ b/src/Umbraco.Tests/Views/textpage1.cshtml @@ -0,0 +1,4 @@ +@inherits Umbraco.Web.Mvc.UmbracoViewPage +@{ + Layout = null; +} \ No newline at end of file diff --git a/src/Umbraco.Core/Logging/WebProfiler.cs b/src/Umbraco.Web/Logging/WebProfiler.cs old mode 100644 new mode 100755 similarity index 97% rename from src/Umbraco.Core/Logging/WebProfiler.cs rename to src/Umbraco.Web/Logging/WebProfiler.cs index 7284ea05bd..77b57e768d --- a/src/Umbraco.Core/Logging/WebProfiler.cs +++ b/src/Umbraco.Web/Logging/WebProfiler.cs @@ -3,8 +3,10 @@ using System.Threading; using System.Web; using StackExchange.Profiling; using StackExchange.Profiling.SqlFormatters; +using Umbraco.Core; +using Umbraco.Core.Logging; -namespace Umbraco.Core.Logging +namespace Umbraco.Web.Logging { /// /// Implements by using the MiniProfiler framework. diff --git a/src/Umbraco.Core/Logging/WebProfilerComponent.cs b/src/Umbraco.Web/Logging/WebProfilerComponent.cs old mode 100644 new mode 100755 similarity index 96% rename from src/Umbraco.Core/Logging/WebProfilerComponent.cs rename to src/Umbraco.Web/Logging/WebProfilerComponent.cs index 338a7e72d6..c6c7b9a545 --- a/src/Umbraco.Core/Logging/WebProfilerComponent.cs +++ b/src/Umbraco.Web/Logging/WebProfilerComponent.cs @@ -1,8 +1,10 @@ using System; using System.Web; +using Umbraco.Core; using Umbraco.Core.Components; +using Umbraco.Core.Logging; -namespace Umbraco.Core.Logging +namespace Umbraco.Web.Logging { internal class WebProfilerComponent : UmbracoComponentBase, IUmbracoCoreComponent { diff --git a/src/Umbraco.Core/Logging/WebProfilerProvider.cs b/src/Umbraco.Web/Logging/WebProfilerProvider.cs old mode 100644 new mode 100755 similarity index 99% rename from src/Umbraco.Core/Logging/WebProfilerProvider.cs rename to src/Umbraco.Web/Logging/WebProfilerProvider.cs index 35ecd002c8..7b12c2f5bd --- a/src/Umbraco.Core/Logging/WebProfilerProvider.cs +++ b/src/Umbraco.Web/Logging/WebProfilerProvider.cs @@ -3,7 +3,7 @@ using System.Threading; using System.Web; using StackExchange.Profiling; -namespace Umbraco.Core.Logging +namespace Umbraco.Web.Logging { /// /// This is a custom MiniProfiler WebRequestProfilerProvider (which is generally the default) that allows diff --git a/src/Umbraco.Web/Runtime/WebRuntime.cs b/src/Umbraco.Web/Runtime/WebRuntime.cs old mode 100644 new mode 100755 index 78610c01b8..da062367e9 --- a/src/Umbraco.Web/Runtime/WebRuntime.cs +++ b/src/Umbraco.Web/Runtime/WebRuntime.cs @@ -1,12 +1,12 @@ using System; using System.Web; using LightInject; -using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; using Umbraco.Core.Runtime; +using Umbraco.Web.Logging; namespace Umbraco.Web.Runtime { @@ -16,6 +16,7 @@ namespace Umbraco.Web.Runtime /// On top of CoreRuntime, handles all of the web-related runtime aspects of Umbraco. public class WebRuntime : CoreRuntime { + private readonly UmbracoApplicationBase _umbracoApplication; private IProfiler _webProfiler; /// @@ -23,8 +24,10 @@ namespace Umbraco.Web.Runtime /// /// public WebRuntime(UmbracoApplicationBase umbracoApplication) - : base(umbracoApplication) - { } + : base() + { + _umbracoApplication = umbracoApplication; + } /// public override void Boot(ServiceContainer container) @@ -54,6 +57,10 @@ namespace Umbraco.Web.Runtime /// public override void Compose(ServiceContainer container) { + // some components may want to initialize with the UmbracoApplicationBase + // well, they should not - we should not do this + // TODO remove this eventually. + container.RegisterInstance(_umbracoApplication); base.Compose(container); // replace CoreRuntime's IProfiler registration diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj old mode 100644 new mode 100755 index 71a285e031..88131ad4e4 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -111,6 +111,9 @@ + + + @@ -181,6 +184,7 @@ + diff --git a/src/Umbraco.Core/UmbracoApplicationBase.cs b/src/Umbraco.Web/UmbracoApplicationBase.cs old mode 100644 new mode 100755 similarity index 99% rename from src/Umbraco.Core/UmbracoApplicationBase.cs rename to src/Umbraco.Web/UmbracoApplicationBase.cs index 1304244ece..7a88e61521 --- a/src/Umbraco.Core/UmbracoApplicationBase.cs +++ b/src/Umbraco.Web/UmbracoApplicationBase.cs @@ -4,11 +4,12 @@ using System.Threading; using System.Web; using System.Web.Hosting; using LightInject; +using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.Logging; using Umbraco.Core.Logging.Serilog; -namespace Umbraco.Core +namespace Umbraco.Web { /// /// Provides an abstract base class for the Umbraco HttpApplication. From c9b2cbc75f4cfd069efba157d4d5f008f1f06109 Mon Sep 17 00:00:00 2001 From: Aaron Powell Date: Mon, 19 Nov 2018 21:26:32 +1100 Subject: [PATCH 2/5] Removing files that weren't meant to be added --- src/Umbraco.Tests/Views/textpage.cshtml | 4 ---- src/Umbraco.Tests/Views/textpage1.cshtml | 4 ---- 2 files changed, 8 deletions(-) delete mode 100755 src/Umbraco.Tests/Views/textpage.cshtml delete mode 100755 src/Umbraco.Tests/Views/textpage1.cshtml diff --git a/src/Umbraco.Tests/Views/textpage.cshtml b/src/Umbraco.Tests/Views/textpage.cshtml deleted file mode 100755 index d7b4dce307..0000000000 --- a/src/Umbraco.Tests/Views/textpage.cshtml +++ /dev/null @@ -1,4 +0,0 @@ -@inherits Umbraco.Web.Mvc.UmbracoViewPage -@{ - Layout = null; -} \ No newline at end of file diff --git a/src/Umbraco.Tests/Views/textpage1.cshtml b/src/Umbraco.Tests/Views/textpage1.cshtml deleted file mode 100755 index d7b4dce307..0000000000 --- a/src/Umbraco.Tests/Views/textpage1.cshtml +++ /dev/null @@ -1,4 +0,0 @@ -@inherits Umbraco.Web.Mvc.UmbracoViewPage -@{ - Layout = null; -} \ No newline at end of file From bcf542506d971a377576f6f42b4cf8f97f7ddef7 Mon Sep 17 00:00:00 2001 From: Aaron Powell Date: Mon, 19 Nov 2018 22:00:50 +1100 Subject: [PATCH 3/5] setting up more of the core in CoreRuntime, this time the logger and Umbraco Core --- src/Umbraco.Core/Runtime/CoreRuntime.cs | 18 ++++++++++++++ .../Runtimes/CoreRuntimeTests.cs | 16 ++++++------- src/Umbraco.Web/UmbracoApplicationBase.cs | 24 ++++--------------- 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/Umbraco.Core/Runtime/CoreRuntime.cs b/src/Umbraco.Core/Runtime/CoreRuntime.cs index 3df69392ca..3038326ea5 100755 --- a/src/Umbraco.Core/Runtime/CoreRuntime.cs +++ b/src/Umbraco.Core/Runtime/CoreRuntime.cs @@ -12,6 +12,7 @@ using Umbraco.Core.Configuration; using Umbraco.Core.Exceptions; using Umbraco.Core.IO; using Umbraco.Core.Logging; +using Umbraco.Core.Logging.Serilog; using Umbraco.Core.Migrations.Upgrade; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Dtos; @@ -42,6 +43,15 @@ namespace Umbraco.Core.Runtime /// public virtual void Boot(ServiceContainer container) { + container.ConfigureUmbracoCore(); // also sets Current.Container + + // register the essential stuff, + // ie the global application logger + // (profiler etc depend on boot manager) + var logger = GetLogger(); + container.RegisterInstance(logger); + // now it is ok to use Current.Logger + Compose(container); // prepare essential stuff @@ -107,6 +117,14 @@ namespace Umbraco.Core.Runtime //sa.Scope?.Dispose(); } + /// + /// Gets a logger. + /// + protected virtual ILogger GetLogger() + { + return SerilogLogger.CreateWithDefaultConfiguration(); + } + private void AquireMainDom(IServiceFactory container) { using (var timer = ProfilingLogger.DebugDuration("Acquiring MainDom.", "Aquired.")) diff --git a/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs b/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs index b3a96021b1..533e2f1a55 100755 --- a/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs +++ b/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs @@ -64,14 +64,6 @@ namespace Umbraco.Tests.Runtimes return new TestRuntime(this); } - // the application's logger is created by the application - // through GetLogger, that custom application can override - protected override ILogger GetLogger() - { - //return Mock.Of(); - return new DebugDiagnosticsLogger(); - } - // don't register anything against AppDomain protected override void ConfigureUnhandledException(ILogger logger) { } @@ -86,6 +78,14 @@ namespace Umbraco.Tests.Runtimes _umbracoApplication = umbracoApplication; } + // the application's logger is created by the application + // through GetLogger, that custom application can override + protected override ILogger GetLogger() + { + //return Mock.Of(); + return new DebugDiagnosticsLogger(); + } + public override void Compose(ServiceContainer container) { base.Compose(container); diff --git a/src/Umbraco.Web/UmbracoApplicationBase.cs b/src/Umbraco.Web/UmbracoApplicationBase.cs index 7a88e61521..aa261ac55f 100755 --- a/src/Umbraco.Web/UmbracoApplicationBase.cs +++ b/src/Umbraco.Web/UmbracoApplicationBase.cs @@ -23,14 +23,6 @@ namespace Umbraco.Web /// protected abstract IRuntime GetRuntime(); - /// - /// Gets a logger. - /// - protected virtual ILogger GetLogger() - { - return SerilogLogger.CreateWithDefaultConfiguration(); - } - // events - in the order they trigger // were part of the BootManager architecture, would trigger only for the initial @@ -62,21 +54,15 @@ namespace Umbraco.Web // create the container for the application, and configure. // the boot manager is responsible for registrations var container = new ServiceContainer(); - container.ConfigureUmbracoCore(); // also sets Current.Container - - // register the essential stuff, - // ie the global application logger - // (profiler etc depend on boot manager) - var logger = GetLogger(); - container.RegisterInstance(logger); - // now it is ok to use Current.Logger - - ConfigureUnhandledException(logger); - ConfigureAssemblyResolve(logger); // get runtime & boot _runtime = GetRuntime(); _runtime.Boot(container); + + var logger = container.GetInstance(); + + ConfigureUnhandledException(logger); + ConfigureAssemblyResolve(logger); } protected virtual void ConfigureUnhandledException(ILogger logger) From 8a809fe97a974f3c0ea1bb98297f0bf8e355224e Mon Sep 17 00:00:00 2001 From: Aaron Powell Date: Mon, 19 Nov 2018 22:02:51 +1100 Subject: [PATCH 4/5] Pushing crash handling on app domain into CoreRuntime --- src/Umbraco.Core/Runtime/CoreRuntime.cs | 36 +++++++++++++++++++++++ src/Umbraco.Web/UmbracoApplicationBase.cs | 36 ----------------------- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/Umbraco.Core/Runtime/CoreRuntime.cs b/src/Umbraco.Core/Runtime/CoreRuntime.cs index 3038326ea5..e62be39f0e 100755 --- a/src/Umbraco.Core/Runtime/CoreRuntime.cs +++ b/src/Umbraco.Core/Runtime/CoreRuntime.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Configuration; +using System.Reflection; using System.Threading; using System.Web; using LightInject; @@ -52,6 +53,9 @@ namespace Umbraco.Core.Runtime container.RegisterInstance(logger); // now it is ok to use Current.Logger + ConfigureUnhandledException(logger); + ConfigureAssemblyResolve(logger); + Compose(container); // prepare essential stuff @@ -125,6 +129,38 @@ namespace Umbraco.Core.Runtime return SerilogLogger.CreateWithDefaultConfiguration(); } + protected virtual void ConfigureUnhandledException(ILogger logger) + { + //take care of unhandled exceptions - there is nothing we can do to + // prevent the launch process to go down but at least we can try + // and log the exception + AppDomain.CurrentDomain.UnhandledException += (_, args) => + { + var exception = (Exception)args.ExceptionObject; + var isTerminating = args.IsTerminating; // always true? + + var msg = "Unhandled exception in AppDomain"; + if (isTerminating) msg += " (terminating)"; + msg += "."; + logger.Error(exception, msg); + }; + } + + protected virtual void ConfigureAssemblyResolve(ILogger logger) + { + // When an assembly can't be resolved. In here we can do magic with the assembly name and try loading another. + // This is used for loading a signed assembly of AutoMapper (v. 3.1+) without having to recompile old code. + AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => + { + // ensure the assembly is indeed AutoMapper and that the PublicKeyToken is null before trying to Load again + // do NOT just replace this with 'return Assembly', as it will cause an infinite loop -> stackoverflow + if (args.Name.StartsWith("AutoMapper") && args.Name.EndsWith("PublicKeyToken=null")) + return Assembly.Load(args.Name.Replace(", PublicKeyToken=null", ", PublicKeyToken=be96cd2c38ef1005")); + return null; + }; + } + + private void AquireMainDom(IServiceFactory container) { using (var timer = ProfilingLogger.DebugDuration("Acquiring MainDom.", "Aquired.")) diff --git a/src/Umbraco.Web/UmbracoApplicationBase.cs b/src/Umbraco.Web/UmbracoApplicationBase.cs index aa261ac55f..080002b18e 100755 --- a/src/Umbraco.Web/UmbracoApplicationBase.cs +++ b/src/Umbraco.Web/UmbracoApplicationBase.cs @@ -58,42 +58,6 @@ namespace Umbraco.Web // get runtime & boot _runtime = GetRuntime(); _runtime.Boot(container); - - var logger = container.GetInstance(); - - ConfigureUnhandledException(logger); - ConfigureAssemblyResolve(logger); - } - - protected virtual void ConfigureUnhandledException(ILogger logger) - { - //take care of unhandled exceptions - there is nothing we can do to - // prevent the entire w3wp process to go down but at least we can try - // and log the exception - AppDomain.CurrentDomain.UnhandledException += (_, args) => - { - var exception = (Exception)args.ExceptionObject; - var isTerminating = args.IsTerminating; // always true? - - var msg = "Unhandled exception in AppDomain"; - if (isTerminating) msg += " (terminating)"; - msg += "."; - logger.Error(exception, msg); - }; - } - - protected virtual void ConfigureAssemblyResolve(ILogger logger) - { - // When an assembly can't be resolved. In here we can do magic with the assembly name and try loading another. - // This is used for loading a signed assembly of AutoMapper (v. 3.1+) without having to recompile old code. - AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => - { - // ensure the assembly is indeed AutoMapper and that the PublicKeyToken is null before trying to Load again - // do NOT just replace this with 'return Assembly', as it will cause an infinite loop -> stackoverflow - if (args.Name.StartsWith("AutoMapper") && args.Name.EndsWith("PublicKeyToken=null")) - return Assembly.Load(args.Name.Replace(", PublicKeyToken=null", ", PublicKeyToken=be96cd2c38ef1005")); - return null; - }; } // called by ASP.NET (auto event wireup) once per app domain From 8aaa75778e820d846ae30d49ee18bc0f5f707936 Mon Sep 17 00:00:00 2001 From: Stephan Date: Tue, 20 Nov 2018 08:35:28 +0100 Subject: [PATCH 5/5] Cleanup --- src/Umbraco.Core/Runtime/CoreRuntime.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Umbraco.Core/Runtime/CoreRuntime.cs b/src/Umbraco.Core/Runtime/CoreRuntime.cs index e62be39f0e..cf2712974d 100755 --- a/src/Umbraco.Core/Runtime/CoreRuntime.cs +++ b/src/Umbraco.Core/Runtime/CoreRuntime.cs @@ -38,8 +38,7 @@ namespace Umbraco.Core.Runtime /// Initializes a new instance of the class. /// public CoreRuntime() - { - } + { } /// public virtual void Boot(ServiceContainer container)