diff --git a/src/Umbraco.Core/Composing/DefaultUmbracoAssemblyProvider.cs b/src/Umbraco.Core/Composing/DefaultUmbracoAssemblyProvider.cs
index 61d7cff240..f7c81d6d7e 100644
--- a/src/Umbraco.Core/Composing/DefaultUmbracoAssemblyProvider.cs
+++ b/src/Umbraco.Core/Composing/DefaultUmbracoAssemblyProvider.cs
@@ -18,6 +18,7 @@ namespace Umbraco.Core.Composing
{
"Umbraco.Core",
"Umbraco.Web",
+ "Umbraco.Web.BackOffice",
"Umbraco.Infrastructure",
"Umbraco.PublishedCache.NuCache",
"Umbraco.ModelsBuilder.Embedded",
diff --git a/src/Umbraco.Core/Hosting/IHostingEnvironment.cs b/src/Umbraco.Core/Hosting/IHostingEnvironment.cs
index 5b97d8e4f3..b12ffbc138 100644
--- a/src/Umbraco.Core/Hosting/IHostingEnvironment.cs
+++ b/src/Umbraco.Core/Hosting/IHostingEnvironment.cs
@@ -19,8 +19,5 @@ namespace Umbraco.Core.Hosting
Version IISVersion { get; }
string MapPath(string path);
string ToAbsolute(string virtualPath, string root);
-
- void RegisterObject(IRegisteredObject registeredObject);
- void UnregisterObject(IRegisteredObject registeredObject);
}
}
diff --git a/src/Umbraco.Core/Hosting/IHostingEnvironmentLifetime.cs b/src/Umbraco.Core/Hosting/IHostingEnvironmentLifetime.cs
new file mode 100644
index 0000000000..891cedad20
--- /dev/null
+++ b/src/Umbraco.Core/Hosting/IHostingEnvironmentLifetime.cs
@@ -0,0 +1,8 @@
+namespace Umbraco.Core.Hosting
+{
+ public interface IHostingEnvironmentLifetime
+ {
+ void RegisterObject(IRegisteredObject registeredObject);
+ void UnregisterObject(IRegisteredObject registeredObject);
+ }
+}
diff --git a/src/Umbraco.Core/Runtime/IMainDom.cs b/src/Umbraco.Core/Runtime/IMainDom.cs
index 444fc1c7d0..1b7f09bc89 100644
--- a/src/Umbraco.Core/Runtime/IMainDom.cs
+++ b/src/Umbraco.Core/Runtime/IMainDom.cs
@@ -1,4 +1,5 @@
using System;
+using Umbraco.Core.Hosting;
// TODO: Can't change namespace due to breaking changes, change in netcore
namespace Umbraco.Core
@@ -16,10 +17,17 @@ namespace Umbraco.Core
/// Gets a value indicating whether the current domain is the main domain.
///
///
- /// When the first call is made to this there will generally be some logic executed to acquire a distributed lock lease.
+ /// Acquire must be called first else this will always return false
///
bool IsMainDom { get; }
+ ///
+ /// Tries to acquire the MainDom, returns true if successful else false
+ ///
+ ///
+ ///
+ bool Acquire(IHostingEnvironmentLifetime hostingEnvironment);
+
///
/// Registers a resource that requires the current AppDomain to be the main domain to function.
///
diff --git a/src/Umbraco.Core/Runtime/MainDom.cs b/src/Umbraco.Core/Runtime/MainDom.cs
index 2c56852095..0a4a250aa6 100644
--- a/src/Umbraco.Core/Runtime/MainDom.cs
+++ b/src/Umbraco.Core/Runtime/MainDom.cs
@@ -21,7 +21,7 @@ namespace Umbraco.Core.Runtime
#region Vars
private readonly ILogger _logger;
- private readonly IHostingEnvironment _hostingEnvironment;
+ private IHostingEnvironmentLifetime _hostingEnvironment;
private readonly IMainDomLock _mainDomLock;
// our own lock for local consistency
@@ -42,17 +42,24 @@ namespace Umbraco.Core.Runtime
#region Ctor
// initializes a new instance of MainDom
- public MainDom(ILogger logger, IHostingEnvironment hostingEnvironment, IMainDomLock systemLock)
+ public MainDom(ILogger logger, IMainDomLock systemLock)
{
- hostingEnvironment.RegisterObject(this);
-
_logger = logger;
- _hostingEnvironment = hostingEnvironment;
_mainDomLock = systemLock;
}
#endregion
+ public bool Acquire(IHostingEnvironmentLifetime hostingEnvironment)
+ {
+ _hostingEnvironment = hostingEnvironment;
+ return LazyInitializer.EnsureInitialized(ref _isMainDom, ref _isInitialized, ref _locko, () =>
+ {
+ hostingEnvironment.RegisterObject(this);
+ return Acquire();
+ });
+ }
+
///
/// Registers a resource that requires the current AppDomain to be the main domain to function.
///
@@ -180,10 +187,9 @@ namespace Umbraco.Core.Runtime
/// Gets a value indicating whether the current domain is the main domain.
///
///
- /// The lazy initializer call will only call the Acquire callback when it's not been initialized, else it will just return
- /// the value from _isMainDom which means when we set _isMainDom to false again after being signaled, this will return false;
+ /// Acquire must be called first else this will always return false
///
- public bool IsMainDom => LazyInitializer.EnsureInitialized(ref _isMainDom, ref _isInitialized, ref _locko, () => Acquire());
+ public bool IsMainDom => _isMainDom;
// IRegisteredObject
void IRegisteredObject.Stop(bool immediate)
diff --git a/src/Umbraco.Core/Scheduling/KeepAlive.cs b/src/Umbraco.Core/Scheduling/KeepAlive.cs
index 515251b105..1c4ef075ae 100644
--- a/src/Umbraco.Core/Scheduling/KeepAlive.cs
+++ b/src/Umbraco.Core/Scheduling/KeepAlive.cs
@@ -11,18 +11,22 @@ namespace Umbraco.Web.Scheduling
{
public class KeepAlive : RecurringTaskBase
{
- private readonly IRuntimeState _runtime;
+ private readonly IRuntimeState _runtimeState;
+ private readonly IMainDom _mainDom;
private readonly IKeepAliveSettings _keepAliveSettings;
private readonly IProfilingLogger _logger;
+ private readonly IServerRegistrar _serverRegistrar;
private static HttpClient _httpClient;
public KeepAlive(IBackgroundTaskRunner runner, int delayMilliseconds, int periodMilliseconds,
- IRuntimeState runtime, IKeepAliveSettings keepAliveSettings, IProfilingLogger logger)
+ IRuntimeState runtimeState, IMainDom mainDom, IKeepAliveSettings keepAliveSettings, IProfilingLogger logger, IServerRegistrar serverRegistrar)
: base(runner, delayMilliseconds, periodMilliseconds)
{
- _runtime = runtime;
+ _runtimeState = runtimeState;
+ _mainDom = mainDom;
_keepAliveSettings = keepAliveSettings;
_logger = logger;
+ _serverRegistrar = serverRegistrar;
if (_httpClient == null)
_httpClient = new HttpClient();
}
@@ -30,7 +34,7 @@ namespace Umbraco.Web.Scheduling
public override async Task PerformRunAsync(CancellationToken token)
{
// not on replicas nor unknown role servers
- switch (_runtime.ServerRole)
+ switch (_serverRegistrar.GetCurrentServerRole())
{
case ServerRole.Replica:
_logger.Debug("Does not run on replica servers.");
@@ -41,7 +45,7 @@ namespace Umbraco.Web.Scheduling
}
// ensure we do not run if not main domain, but do NOT lock it
- if (_runtime.IsMainDom == false)
+ if (_mainDom.IsMainDom == false)
{
_logger.Debug("Does not run if not MainDom.");
return false; // do NOT repeat, going down
@@ -54,7 +58,7 @@ namespace Umbraco.Web.Scheduling
{
if (keepAlivePingUrl.Contains("{umbracoApplicationUrl}"))
{
- var umbracoAppUrl = _runtime.ApplicationUrl.ToString();
+ var umbracoAppUrl = _runtimeState.ApplicationUrl.ToString();
if (umbracoAppUrl.IsNullOrWhiteSpace())
{
_logger.Warn("No umbracoApplicationUrl for service (yet), skip.");
diff --git a/src/Umbraco.Core/Scheduling/TempFileCleanup.cs b/src/Umbraco.Core/Scheduling/TempFileCleanup.cs
index aefaf605db..90bf4ee9eb 100644
--- a/src/Umbraco.Core/Scheduling/TempFileCleanup.cs
+++ b/src/Umbraco.Core/Scheduling/TempFileCleanup.cs
@@ -14,26 +14,26 @@ namespace Umbraco.Web.Scheduling
{
private readonly DirectoryInfo[] _tempFolders;
private readonly TimeSpan _age;
- private readonly IRuntimeState _runtime;
+ private readonly IMainDom _mainDom;
private readonly IProfilingLogger _logger;
public TempFileCleanup(IBackgroundTaskRunner runner, int delayMilliseconds, int periodMilliseconds,
IEnumerable tempFolders, TimeSpan age,
- IRuntimeState runtime, IProfilingLogger logger)
+ IMainDom mainDom, IProfilingLogger logger)
: base(runner, delayMilliseconds, periodMilliseconds)
{
//SystemDirectories.TempFileUploads
_tempFolders = tempFolders.ToArray();
_age = age;
- _runtime = runtime;
+ _mainDom = mainDom;
_logger = logger;
}
public override bool PerformRun()
{
// ensure we do not run if not main domain
- if (_runtime.IsMainDom == false)
+ if (_mainDom.IsMainDom == false)
{
_logger.Debug("Does not run if not MainDom.");
return false; // do NOT repeat, going down
diff --git a/src/Umbraco.Core/Services/IRuntime.cs b/src/Umbraco.Core/Services/IRuntime.cs
index e846342dbc..4715068073 100644
--- a/src/Umbraco.Core/Services/IRuntime.cs
+++ b/src/Umbraco.Core/Services/IRuntime.cs
@@ -13,13 +13,15 @@ namespace Umbraco.Core
///
/// The application register.
/// The application factory.
- IFactory Boot(IRegister register);
+ IFactory Configure(IRegister register);
///
/// Gets the runtime state.
///
IRuntimeState State { get; }
+ void Start();
+
///
/// Terminates the runtime.
///
diff --git a/src/Umbraco.Core/Services/IRuntimeState.cs b/src/Umbraco.Core/Services/IRuntimeState.cs
index 565b2563e6..4b5e26651b 100644
--- a/src/Umbraco.Core/Services/IRuntimeState.cs
+++ b/src/Umbraco.Core/Services/IRuntimeState.cs
@@ -25,21 +25,6 @@ namespace Umbraco.Core
///
SemVersion SemanticVersion { get; }
- ///
- /// Gets a value indicating whether the application is running in debug mode.
- ///
- bool Debug { get; }
-
- ///
- /// Gets a value indicating whether the runtime is the current main domain.
- ///
- bool IsMainDom { get; }
-
- ///
- /// Get the server's current role.
- ///
- ServerRole ServerRole { get; }
-
///
/// Gets the Umbraco application url.
///
@@ -71,6 +56,5 @@ namespace Umbraco.Core
///
BootFailedException BootFailedException { get; }
- IMainDom MainDom { get; }
}
}
diff --git a/src/Umbraco.Core/SimpleMainDom.cs b/src/Umbraco.Core/SimpleMainDom.cs
index 87cc7bcff1..52ed6c1d91 100644
--- a/src/Umbraco.Core/SimpleMainDom.cs
+++ b/src/Umbraco.Core/SimpleMainDom.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using Umbraco.Core.Hosting;
namespace Umbraco.Core
{
@@ -16,6 +17,9 @@ namespace Umbraco.Core
///
public bool IsMainDom { get; private set; } = true;
+ // always acquire
+ public bool Acquire(IHostingEnvironmentLifetime hostingEnvironment) => true;
+
///
public bool Register(Action release, int weight = 100)
=> Register(null, release, weight);
diff --git a/src/Umbraco.Infrastructure/BatchedDatabaseServerMessenger.cs b/src/Umbraco.Infrastructure/BatchedDatabaseServerMessenger.cs
index 78b9589a2e..70b79fbeb0 100644
--- a/src/Umbraco.Infrastructure/BatchedDatabaseServerMessenger.cs
+++ b/src/Umbraco.Infrastructure/BatchedDatabaseServerMessenger.cs
@@ -28,17 +28,18 @@ namespace Umbraco.Web
private readonly IRequestAccessor _requestAccessor;
public BatchedDatabaseServerMessenger(
- IRuntimeState runtime,
+ IMainDom mainDom,
IUmbracoDatabaseFactory databaseFactory,
IScopeProvider scopeProvider,
ISqlContext sqlContext,
IProfilingLogger proflog,
+ IServerRegistrar serverRegistrar,
DatabaseServerMessengerOptions options,
IHostingEnvironment hostingEnvironment,
CacheRefresherCollection cacheRefreshers,
IRequestCache requestCache,
IRequestAccessor requestAccessor)
- : base(runtime, scopeProvider, sqlContext, proflog, true, options, hostingEnvironment, cacheRefreshers)
+ : base(mainDom, scopeProvider, sqlContext, proflog, serverRegistrar, true, options, hostingEnvironment, cacheRefreshers)
{
_databaseFactory = databaseFactory;
_requestCache = requestCache;
diff --git a/src/Umbraco.Infrastructure/Compose/DatabaseServerRegistrarAndMessengerComponent.cs b/src/Umbraco.Infrastructure/Compose/DatabaseServerRegistrarAndMessengerComponent.cs
index 2a24e6f318..4e183b9211 100644
--- a/src/Umbraco.Infrastructure/Compose/DatabaseServerRegistrarAndMessengerComponent.cs
+++ b/src/Umbraco.Infrastructure/Compose/DatabaseServerRegistrarAndMessengerComponent.cs
@@ -91,7 +91,6 @@ namespace Umbraco.Web.Compose
private readonly BackgroundTaskRunner _processTaskRunner;
private bool _started;
private IBackgroundTask[] _tasks;
- private IndexRebuilder _indexRebuilder;
private readonly IRequestAccessor _requestAccessor;
public DatabaseServerRegistrarAndMessengerComponent(
@@ -100,14 +99,12 @@ namespace Umbraco.Web.Compose
IServerMessenger serverMessenger,
IServerRegistrationService registrationService,
ILogger logger,
- IHostingEnvironment hostingEnvironment,
- IndexRebuilder indexRebuilder,
+ IHostingEnvironmentLifetime hostingEnvironment,
IRequestAccessor requestAccessor)
{
_runtime = runtime;
_logger = logger;
_registrationService = registrationService;
- _indexRebuilder = indexRebuilder;
_requestAccessor = requestAccessor;
// create task runner for DatabaseServerRegistrar
diff --git a/src/Umbraco.Infrastructure/Compose/ManifestWatcherComponent.cs b/src/Umbraco.Infrastructure/Compose/ManifestWatcherComponent.cs
index d4e22bbfde..06b3cc0cc9 100644
--- a/src/Umbraco.Infrastructure/Compose/ManifestWatcherComponent.cs
+++ b/src/Umbraco.Infrastructure/Compose/ManifestWatcherComponent.cs
@@ -4,13 +4,13 @@ using Umbraco.Core.Hosting;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Manifest;
-using Umbraco.Net;
+using Umbraco.Core.Net;
namespace Umbraco.Core.Compose
{
public sealed class ManifestWatcherComponent : IComponent
{
- private readonly IRuntimeState _runtimeState;
+ private readonly IHostingEnvironment _hosting;
private readonly ILogger _logger;
private readonly IIOHelper _ioHelper;
private readonly IUmbracoApplicationLifetime _umbracoApplicationLifetime;
@@ -19,9 +19,9 @@ namespace Umbraco.Core.Compose
// package.manifest chances and restarts the application on any change
private ManifestWatcher _mw;
- public ManifestWatcherComponent(IRuntimeState runtimeState, ILogger logger, IIOHelper ioHelper, IUmbracoApplicationLifetime umbracoApplicationLifetime)
+ public ManifestWatcherComponent(IHostingEnvironment hosting, ILogger logger, IIOHelper ioHelper, IUmbracoApplicationLifetime umbracoApplicationLifetime)
{
- _runtimeState = runtimeState;
+ _hosting = hosting;
_logger = logger;
_ioHelper = ioHelper;
_umbracoApplicationLifetime = umbracoApplicationLifetime;
@@ -29,7 +29,7 @@ namespace Umbraco.Core.Compose
public void Initialize()
{
- if (_runtimeState.Debug == false) return;
+ if (_hosting.IsDebugMode == false) return;
//if (ApplicationContext.Current.IsConfigured == false || GlobalSettings.DebugMode == false)
// return;
diff --git a/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs b/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs
index 67cfcded92..1bf954e4c1 100644
--- a/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs
+++ b/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs
@@ -44,7 +44,7 @@ namespace Umbraco.Core.Runtime
public override void Compose(Composition composition)
{
base.Compose(composition);
-
+
// composers
composition
.ComposeRepositories()
@@ -120,10 +120,11 @@ namespace Umbraco.Core.Runtime
// project
composition.RegisterUnique(factory
=> new DatabaseServerMessenger(
- factory.GetInstance(),
+ factory.GetInstance(),
factory.GetInstance(),
factory.GetInstance(),
factory.GetInstance(),
+ factory.GetInstance(),
true, new DatabaseServerMessengerOptions(),
factory.GetInstance(),
factory.GetInstance()
diff --git a/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs b/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs
index 5cd51a174a..89ec036607 100644
--- a/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs
+++ b/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
-using System.Reflection;
using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
@@ -12,7 +11,6 @@ using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Mappers;
-using Umbraco.Core.Sync;
namespace Umbraco.Core.Runtime
{
@@ -25,12 +23,26 @@ namespace Umbraco.Core.Runtime
{
private ComponentCollection _components;
private IFactory _factory;
- private RuntimeState _state;
+ private readonly RuntimeState _state;
private readonly IUmbracoBootPermissionChecker _umbracoBootPermissionChecker;
private readonly IGlobalSettings _globalSettings;
private readonly IConnectionStrings _connectionStrings;
+ ///
+ /// Constructor
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
public CoreRuntime(
Configs configs,
IUmbracoVersion umbracoVersion,
@@ -65,11 +77,7 @@ namespace Umbraco.Core.Runtime
// runtime state
// beware! must use '() => _factory.GetInstance()' and NOT '_factory.GetInstance'
// as the second one captures the current value (null) and therefore fails
- _state = new RuntimeState(Logger,
- Configs.Global(),
- new Lazy(() => mainDom),
- new Lazy(() => _factory.GetInstance()),
- UmbracoVersion, HostingEnvironment, BackOfficeInfo)
+ _state = new RuntimeState(Logger, Configs.Global(), UmbracoVersion, BackOfficeInfo)
{
Level = RuntimeLevel.Boot
};
@@ -81,12 +89,13 @@ namespace Umbraco.Core.Runtime
protected ILogger Logger { get; }
protected IBackOfficeInfo BackOfficeInfo { get; }
+
public IDbProviderFactoryCreator DbProviderFactoryCreator { get; }
///
/// Gets the profiler.
///
- protected IProfiler Profiler { get; set; }
+ protected IProfiler Profiler { get; }
///
/// Gets the profiling logger.
@@ -109,10 +118,10 @@ namespace Umbraco.Core.Runtime
///
public IRuntimeState State => _state;
- public IMainDom MainDom { get; private set; }
+ public IMainDom MainDom { get; }
///
- public virtual IFactory Boot(IRegister register)
+ public virtual IFactory Configure(IRegister register)
{
if (register is null) throw new ArgumentNullException(nameof(register));
@@ -140,28 +149,24 @@ namespace Umbraco.Core.Runtime
// application environment
ConfigureUnhandledException();
- ConfigureApplicationRootPath();
-
- Boot(register, timer);
+ return _factory = Configure(register, timer);
}
-
- return _factory;
}
///
- /// Boots the runtime within a timer.
+ /// Configure the runtime within a timer.
///
- protected virtual IFactory Boot(IRegister register, DisposableTimer timer)
+ private IFactory Configure(IRegister register, DisposableTimer timer)
{
if (register is null) throw new ArgumentNullException(nameof(register));
if (timer is null) throw new ArgumentNullException(nameof(timer));
Composition composition = null;
+ IFactory factory = null;
try
{
- // throws if not full-trust
- _umbracoBootPermissionChecker.ThrowIfNotPermissions();
+
// run handlers
RuntimeOptions.DoRuntimeBoot(ProfilingLogger);
@@ -179,15 +184,8 @@ namespace Umbraco.Core.Runtime
composition = new Composition(register, typeLoader, ProfilingLogger, _state, Configs, IOHelper, appCaches);
composition.RegisterEssentials(Logger, Profiler, ProfilingLogger, MainDom, appCaches, databaseFactory, typeLoader, _state, TypeFinder, IOHelper, UmbracoVersion, DbProviderFactoryCreator, HostingEnvironment, BackOfficeInfo);
- // run handlers
- RuntimeOptions.DoRuntimeEssentials(composition, appCaches, typeLoader, databaseFactory);
-
- // register runtime-level services
- // there should be none, really - this is here "just in case"
- Compose(composition);
-
- // acquire the main domain - if this fails then anything that should be registered with MainDom will not operate
- AcquireMainDom(MainDom);
+ // register ourselves (TODO: Should we put this in RegisterEssentials?)
+ composition.Register(_ => this, Lifetime.Singleton);
// determine our runtime level
DetermineRuntimeLevel(databaseFactory, ProfilingLogger);
@@ -205,13 +203,7 @@ namespace Umbraco.Core.Runtime
composers.Compose();
// create the factory
- _factory = composition.CreateFactory();
-
- // create & initialize the components
- _components = _factory.GetInstance();
- _components.Initialize();
-
-
+ factory = composition.CreateFactory();
}
catch (Exception e)
{
@@ -228,11 +220,11 @@ namespace Umbraco.Core.Runtime
// if something goes wrong above, we may end up with no factory
// meaning nothing can get the runtime state, etc - so let's try
// to make sure we have a factory
- if (_factory == null)
+ if (factory == null)
{
try
{
- _factory = composition?.CreateFactory();
+ factory = composition?.CreateFactory();
}
catch { /* yea */ }
}
@@ -246,7 +238,29 @@ namespace Umbraco.Core.Runtime
// throw a BootFailedException for every requests.
}
- return _factory;
+ return factory;
+ }
+
+ public void Start()
+ {
+ // throws if not full-trust
+ _umbracoBootPermissionChecker.ThrowIfNotPermissions();
+
+ ConfigureApplicationRootPath();
+
+ // run handlers
+ RuntimeOptions.DoRuntimeEssentials(_factory);
+
+ var hostingEnvironmentLifetime = _factory.TryGetInstance();
+ if (hostingEnvironmentLifetime == null)
+ throw new InvalidOperationException($"An instance of {typeof(IHostingEnvironmentLifetime)} could not be resolved from the container, ensure that one if registered in your runtime before calling {nameof(IRuntime)}.{nameof(Start)}");
+
+ // acquire the main domain - if this fails then anything that should be registered with MainDom will not operate
+ AcquireMainDom(MainDom, _factory.GetInstance());
+
+ // create & initialize the components
+ _components = _factory.GetInstance();
+ _components.Initialize();
}
protected virtual void ConfigureUnhandledException()
@@ -273,13 +287,13 @@ namespace Umbraco.Core.Runtime
IOHelper.SetRootDirectory(path);
}
- private bool AcquireMainDom(IMainDom mainDom)
+ private bool AcquireMainDom(IMainDom mainDom, IHostingEnvironmentLifetime hostingEnvironmentLifetime)
{
using (var timer = ProfilingLogger.DebugDuration("Acquiring MainDom.", "Acquired."))
{
try
{
- return mainDom.IsMainDom;
+ return mainDom.Acquire(hostingEnvironmentLifetime);
}
catch
{
@@ -338,12 +352,6 @@ namespace Umbraco.Core.Runtime
_components?.Terminate();
}
- ///
- /// Composes the runtime.
- ///
- public virtual void Compose(Composition composition)
- {
- }
#region Getters
@@ -384,5 +392,6 @@ namespace Umbraco.Core.Runtime
#endregion
+
}
}
diff --git a/src/Umbraco.Infrastructure/Runtime/WebRuntime.cs b/src/Umbraco.Infrastructure/Runtime/WebRuntime.cs
index 2f45a3e437..fc2a019023 100644
--- a/src/Umbraco.Infrastructure/Runtime/WebRuntime.cs
+++ b/src/Umbraco.Infrastructure/Runtime/WebRuntime.cs
@@ -40,7 +40,7 @@ namespace Umbraco.Web.Runtime
}
///
- public override IFactory Boot(IRegister register)
+ public override IFactory Configure(IRegister register)
{
var profilingLogger = new ProfilingLogger(Logger, Profiler);
@@ -57,7 +57,7 @@ namespace Umbraco.Web.Runtime
NetworkHelper.MachineName);
Logger.Debug("Runtime: {Runtime}", GetType().FullName);
- var factory = base.Boot(register);
+ var factory = base.Configure(register);
// now (and only now) is the time to switch over to perWebRequest scopes.
// up until that point we may not have a request, and scoped services would
diff --git a/src/Umbraco.Infrastructure/RuntimeOptions.cs b/src/Umbraco.Infrastructure/RuntimeOptions.cs
index 23abd474a4..562a7e3c5c 100644
--- a/src/Umbraco.Infrastructure/RuntimeOptions.cs
+++ b/src/Umbraco.Infrastructure/RuntimeOptions.cs
@@ -16,7 +16,7 @@ namespace Umbraco.Core
public static class RuntimeOptions
{
private static List> _onBoot;
- private static List> _onEssentials;
+ private static List> _onEssentials;
///
/// Executes the RuntimeBoot handlers.
@@ -33,13 +33,13 @@ namespace Umbraco.Core
///
/// Executes the RuntimeEssentials handlers.
///
- internal static void DoRuntimeEssentials(Composition composition, AppCaches appCaches, TypeLoader typeLoader, IUmbracoDatabaseFactory databaseFactory)
+ internal static void DoRuntimeEssentials(IFactory factory)
{
if (_onEssentials== null)
return;
foreach (var action in _onEssentials)
- action(composition, appCaches, typeLoader, databaseFactory);
+ action(factory);
}
///
@@ -64,10 +64,10 @@ namespace Umbraco.Core
/// essential things (AppCaches, a TypeLoader, and a database factory) but
/// before anything else.
///
- public static void OnRuntimeEssentials(Action action)
+ public static void OnRuntimeEssentials(Action action)
{
if (_onEssentials == null)
- _onEssentials = new List>();
+ _onEssentials = new List>();
_onEssentials.Add(action);
}
}
diff --git a/src/Umbraco.Infrastructure/RuntimeState.cs b/src/Umbraco.Infrastructure/RuntimeState.cs
index 420fba7ffc..e0099c5e7e 100644
--- a/src/Umbraco.Infrastructure/RuntimeState.cs
+++ b/src/Umbraco.Infrastructure/RuntimeState.cs
@@ -22,44 +22,22 @@ namespace Umbraco.Core
private readonly ILogger _logger;
private readonly IGlobalSettings _globalSettings;
private readonly ConcurrentHashSet _applicationUrls = new ConcurrentHashSet();
- private readonly Lazy _mainDom;
- private readonly Lazy _serverRegistrar;
private readonly IUmbracoVersion _umbracoVersion;
- private readonly IHostingEnvironment _hostingEnvironment;
private readonly IBackOfficeInfo _backOfficeInfo;
///
/// Initializes a new instance of the class.
///
public RuntimeState(ILogger logger, IGlobalSettings globalSettings,
- Lazy mainDom, Lazy serverRegistrar, IUmbracoVersion umbracoVersion,
- IHostingEnvironment hostingEnvironment,
+ IUmbracoVersion umbracoVersion,
IBackOfficeInfo backOfficeInfo)
{
_logger = logger;
_globalSettings = globalSettings;
- _mainDom = mainDom;
- _serverRegistrar = serverRegistrar;
_umbracoVersion = umbracoVersion;
- _hostingEnvironment = hostingEnvironment;
_backOfficeInfo = backOfficeInfo;
}
- ///
- /// Gets the server registrar.
- ///
- ///
- /// This is NOT exposed in the interface.
- ///
- private IServerRegistrar ServerRegistrar => _serverRegistrar.Value;
-
- ///
- /// Gets the application MainDom.
- ///
- ///
- /// This is NOT exposed in the interface as MainDom is internal.
- ///
- public IMainDom MainDom => _mainDom.Value;
///
public Version Version => _umbracoVersion.Current;
@@ -70,23 +48,14 @@ namespace Umbraco.Core
///
public SemVersion SemanticVersion => _umbracoVersion.SemanticVersion;
- ///
- public bool Debug => _hostingEnvironment.IsDebugMode;
-
- ///
- public bool IsMainDom => MainDom.IsMainDom;
-
- ///
- public ServerRole ServerRole => ServerRegistrar.GetCurrentServerRole();
-
///
public Uri ApplicationUrl { get; private set; }
///
- public string CurrentMigrationState { get; internal set; }
+ public string CurrentMigrationState { get; private set; }
///
- public string FinalMigrationState { get; internal set; }
+ public string FinalMigrationState { get; private set; }
///
public RuntimeLevel Level { get; internal set; } = RuntimeLevel.Unknown;
@@ -248,7 +217,7 @@ namespace Umbraco.Core
Reason = RuntimeLevelReason.UpgradeMigrations;
}
- protected virtual bool EnsureUmbracoUpgradeState(IUmbracoDatabaseFactory databaseFactory, ILogger logger)
+ private bool EnsureUmbracoUpgradeState(IUmbracoDatabaseFactory databaseFactory, ILogger logger)
{
var upgrader = new Upgrader(new UmbracoPlan(_umbracoVersion, _globalSettings));
var stateValueKey = upgrader.StateValueKey;
diff --git a/src/Umbraco.Infrastructure/Scheduling/BackgroundTaskRunner.cs b/src/Umbraco.Infrastructure/Scheduling/BackgroundTaskRunner.cs
index 0b5b81319f..31884992f7 100644
--- a/src/Umbraco.Infrastructure/Scheduling/BackgroundTaskRunner.cs
+++ b/src/Umbraco.Infrastructure/Scheduling/BackgroundTaskRunner.cs
@@ -81,7 +81,7 @@ namespace Umbraco.Web.Scheduling
private readonly string _logPrefix;
private readonly BackgroundTaskRunnerOptions _options;
private readonly ILogger _logger;
- private readonly IHostingEnvironment _hostingEnvironment;
+ private readonly IHostingEnvironmentLifetime _hostingEnvironment;
private readonly object _locker = new object();
private readonly BufferBlock _tasks = new BufferBlock(new DataflowBlockOptions());
@@ -105,7 +105,7 @@ namespace Umbraco.Web.Scheduling
/// A logger.
/// The hosting environment
/// An optional main domain hook.
- public BackgroundTaskRunner(ILogger logger, IHostingEnvironment hostingEnvironment, MainDomHook hook = null)
+ public BackgroundTaskRunner(ILogger logger, IHostingEnvironmentLifetime hostingEnvironment, MainDomHook hook = null)
: this(typeof(T).FullName, new BackgroundTaskRunnerOptions(), logger, hostingEnvironment, hook)
{ }
@@ -116,7 +116,7 @@ namespace Umbraco.Web.Scheduling
/// A logger.
/// The hosting environment
/// An optional main domain hook.
- public BackgroundTaskRunner(string name, ILogger logger, IHostingEnvironment hostingEnvironment, MainDomHook hook = null)
+ public BackgroundTaskRunner(string name, ILogger logger, IHostingEnvironmentLifetime hostingEnvironment, MainDomHook hook = null)
: this(name, new BackgroundTaskRunnerOptions(), logger, hostingEnvironment, hook)
{ }
@@ -127,7 +127,7 @@ namespace Umbraco.Web.Scheduling
/// A logger.
/// The hosting environment
/// An optional main domain hook.
- public BackgroundTaskRunner(BackgroundTaskRunnerOptions options, ILogger logger, IHostingEnvironment hostingEnvironment, MainDomHook hook = null)
+ public BackgroundTaskRunner(BackgroundTaskRunnerOptions options, ILogger logger, IHostingEnvironmentLifetime hostingEnvironment, MainDomHook hook = null)
: this(typeof(T).FullName, options, logger, hostingEnvironment, hook)
{ }
@@ -139,7 +139,7 @@ namespace Umbraco.Web.Scheduling
/// A logger.
/// The hosting environment
/// An optional main domain hook.
- public BackgroundTaskRunner(string name, BackgroundTaskRunnerOptions options, ILogger logger, IHostingEnvironment hostingEnvironment, MainDomHook hook = null)
+ public BackgroundTaskRunner(string name, BackgroundTaskRunnerOptions options, ILogger logger, IHostingEnvironmentLifetime hostingEnvironment, MainDomHook hook = null)
{
_options = options ?? throw new ArgumentNullException(nameof(options));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
diff --git a/src/Umbraco.Infrastructure/Scheduling/HealthCheckNotifier.cs b/src/Umbraco.Infrastructure/Scheduling/HealthCheckNotifier.cs
index 04c1571b3b..e7692b851a 100644
--- a/src/Umbraco.Infrastructure/Scheduling/HealthCheckNotifier.cs
+++ b/src/Umbraco.Infrastructure/Scheduling/HealthCheckNotifier.cs
@@ -11,22 +11,27 @@ namespace Umbraco.Web.Scheduling
{
public class HealthCheckNotifier : RecurringTaskBase
{
- private readonly IRuntimeState _runtimeState;
+ private readonly IMainDom _mainDom;
private readonly HealthCheckCollection _healthChecks;
private readonly HealthCheckNotificationMethodCollection _notifications;
private readonly IProfilingLogger _logger;
private readonly IHealthChecksSettings _healthChecksSettingsConfig;
+ private readonly IServerRegistrar _serverRegistrar;
+ private readonly IRuntimeState _runtimeState;
public HealthCheckNotifier(IBackgroundTaskRunner runner, int delayMilliseconds, int periodMilliseconds,
HealthCheckCollection healthChecks, HealthCheckNotificationMethodCollection notifications,
- IRuntimeState runtimeState, IProfilingLogger logger, IHealthChecksSettings healthChecksSettingsConfig)
+ IMainDom mainDom, IProfilingLogger logger, IHealthChecksSettings healthChecksSettingsConfig, IServerRegistrar serverRegistrar,
+ IRuntimeState runtimeState)
: base(runner, delayMilliseconds, periodMilliseconds)
{
_healthChecks = healthChecks;
_notifications = notifications;
- _runtimeState = runtimeState;
+ _mainDom = mainDom;
_logger = logger;
_healthChecksSettingsConfig = healthChecksSettingsConfig;
+ _serverRegistrar = serverRegistrar;
+ _runtimeState = runtimeState;
}
public override async Task PerformRunAsync(CancellationToken token)
@@ -34,7 +39,7 @@ namespace Umbraco.Web.Scheduling
if (_runtimeState.Level != RuntimeLevel.Run)
return true; // repeat...
- switch (_runtimeState.ServerRole)
+ switch (_serverRegistrar.GetCurrentServerRole())
{
case ServerRole.Replica:
_logger.Debug("Does not run on replica servers.");
@@ -45,7 +50,7 @@ namespace Umbraco.Web.Scheduling
}
// ensure we do not run if not main domain, but do NOT lock it
- if (_runtimeState.IsMainDom == false)
+ if (_mainDom.IsMainDom == false)
{
_logger.Debug("Does not run if not MainDom.");
return false; // do NOT repeat, going down
diff --git a/src/Umbraco.Infrastructure/Scheduling/LogScrubber.cs b/src/Umbraco.Infrastructure/Scheduling/LogScrubber.cs
index 563d79a193..aaf09dbe8f 100644
--- a/src/Umbraco.Infrastructure/Scheduling/LogScrubber.cs
+++ b/src/Umbraco.Infrastructure/Scheduling/LogScrubber.cs
@@ -11,17 +11,19 @@ namespace Umbraco.Web.Scheduling
public class LogScrubber : RecurringTaskBase
{
- private readonly IRuntimeState _runtime;
+ private readonly IMainDom _mainDom;
+ private readonly IServerRegistrar _serverRegistrar;
private readonly IAuditService _auditService;
private readonly ILoggingSettings _settings;
private readonly IProfilingLogger _logger;
private readonly IScopeProvider _scopeProvider;
public LogScrubber(IBackgroundTaskRunner runner, int delayMilliseconds, int periodMilliseconds,
- IRuntimeState runtime, IAuditService auditService, ILoggingSettings settings, IScopeProvider scopeProvider, IProfilingLogger logger)
+ IMainDom mainDom, IServerRegistrar serverRegistrar, IAuditService auditService, ILoggingSettings settings, IScopeProvider scopeProvider, IProfilingLogger logger)
: base(runner, delayMilliseconds, periodMilliseconds)
{
- _runtime = runtime;
+ _mainDom = mainDom;
+ _serverRegistrar = serverRegistrar;
_auditService = auditService;
_settings = settings;
_scopeProvider = scopeProvider;
@@ -53,7 +55,7 @@ namespace Umbraco.Web.Scheduling
public override bool PerformRun()
{
- switch (_runtime.ServerRole)
+ switch (_serverRegistrar.GetCurrentServerRole())
{
case ServerRole.Replica:
_logger.Debug("Does not run on replica servers.");
@@ -64,7 +66,7 @@ namespace Umbraco.Web.Scheduling
}
// ensure we do not run if not main domain, but do NOT lock it
- if (_runtime.IsMainDom == false)
+ if (_mainDom.IsMainDom == false)
{
_logger.Debug("Does not run if not MainDom.");
return false; // do NOT repeat, going down
diff --git a/src/Umbraco.Infrastructure/Scheduling/ScheduledPublishing.cs b/src/Umbraco.Infrastructure/Scheduling/ScheduledPublishing.cs
index b074704033..fea16999fd 100644
--- a/src/Umbraco.Infrastructure/Scheduling/ScheduledPublishing.cs
+++ b/src/Umbraco.Infrastructure/Scheduling/ScheduledPublishing.cs
@@ -10,16 +10,20 @@ namespace Umbraco.Web.Scheduling
public class ScheduledPublishing : RecurringTaskBase
{
private readonly IRuntimeState _runtime;
+ private readonly IMainDom _mainDom;
+ private readonly IServerRegistrar _serverRegistrar;
private readonly IContentService _contentService;
private readonly IUmbracoContextFactory _umbracoContextFactory;
private readonly ILogger _logger;
private readonly IServerMessenger _serverMessenger;
public ScheduledPublishing(IBackgroundTaskRunner runner, int delayMilliseconds, int periodMilliseconds,
- IRuntimeState runtime, IContentService contentService, IUmbracoContextFactory umbracoContextFactory, ILogger logger, IServerMessenger serverMessenger)
+ IRuntimeState runtime, IMainDom mainDom, IServerRegistrar serverRegistrar, IContentService contentService, IUmbracoContextFactory umbracoContextFactory, ILogger logger, IServerMessenger serverMessenger)
: base(runner, delayMilliseconds, periodMilliseconds)
{
_runtime = runtime;
+ _mainDom = mainDom;
+ _serverRegistrar = serverRegistrar;
_contentService = contentService;
_umbracoContextFactory = umbracoContextFactory;
_logger = logger;
@@ -31,7 +35,7 @@ namespace Umbraco.Web.Scheduling
if (Suspendable.ScheduledPublishing.CanRun == false)
return true; // repeat, later
- switch (_runtime.ServerRole)
+ switch (_serverRegistrar.GetCurrentServerRole())
{
case ServerRole.Replica:
_logger.Debug("Does not run on replica servers.");
@@ -42,7 +46,7 @@ namespace Umbraco.Web.Scheduling
}
// ensure we do not run if not main domain, but do NOT lock it
- if (_runtime.IsMainDom == false)
+ if (_mainDom.IsMainDom == false)
{
_logger.Debug("Does not run if not MainDom.");
return false; // do NOT repeat, going down
diff --git a/src/Umbraco.Infrastructure/Scheduling/SchedulerComponent.cs b/src/Umbraco.Infrastructure/Scheduling/SchedulerComponent.cs
index c8ff67579a..c867d81d69 100644
--- a/src/Umbraco.Infrastructure/Scheduling/SchedulerComponent.cs
+++ b/src/Umbraco.Infrastructure/Scheduling/SchedulerComponent.cs
@@ -26,10 +26,12 @@ namespace Umbraco.Web.Scheduling
private const int OneHourMilliseconds = 3600000;
private readonly IRuntimeState _runtime;
+ private readonly IMainDom _mainDom;
+ private readonly IServerRegistrar _serverRegistrar;
private readonly IContentService _contentService;
private readonly IAuditService _auditService;
private readonly IProfilingLogger _logger;
- private readonly IHostingEnvironment _hostingEnvironment;
+ private readonly IHostingEnvironmentLifetime _hostingEnvironment;
private readonly IScopeProvider _scopeProvider;
private readonly HealthCheckCollection _healthChecks;
private readonly HealthCheckNotificationMethodCollection _notifications;
@@ -43,7 +45,6 @@ namespace Umbraco.Web.Scheduling
private BackgroundTaskRunner _keepAliveRunner;
private BackgroundTaskRunner _publishingRunner;
- private BackgroundTaskRunner _tasksRunner;
private BackgroundTaskRunner _scrubberRunner;
private BackgroundTaskRunner _fileCleanupRunner;
private BackgroundTaskRunner _healthCheckRunner;
@@ -52,15 +53,17 @@ namespace Umbraco.Web.Scheduling
private object _locker = new object();
private IBackgroundTask[] _tasks;
- public SchedulerComponent(IRuntimeState runtime,
+ public SchedulerComponent(IRuntimeState runtime, IMainDom mainDom, IServerRegistrar serverRegistrar,
IContentService contentService, IAuditService auditService,
HealthCheckCollection healthChecks, HealthCheckNotificationMethodCollection notifications,
IScopeProvider scopeProvider, IUmbracoContextFactory umbracoContextFactory, IProfilingLogger logger,
- IHostingEnvironment hostingEnvironment, IHealthChecksSettings healthChecksSettingsConfig,
+ IHostingEnvironmentLifetime hostingEnvironment, IHealthChecksSettings healthChecksSettingsConfig,
IIOHelper ioHelper, IServerMessenger serverMessenger, IRequestAccessor requestAccessor,
ILoggingSettings loggingSettings, IKeepAliveSettings keepAliveSettings)
{
_runtime = runtime;
+ _mainDom = mainDom;
+ _serverRegistrar = serverRegistrar;
_contentService = contentService;
_auditService = auditService;
_scopeProvider = scopeProvider;
@@ -83,7 +86,6 @@ namespace Umbraco.Web.Scheduling
// backgrounds runners are web aware, if the app domain dies, these tasks will wind down correctly
_keepAliveRunner = new BackgroundTaskRunner("KeepAlive", _logger, _hostingEnvironment);
_publishingRunner = new BackgroundTaskRunner("ScheduledPublishing", _logger, _hostingEnvironment);
- _tasksRunner = new BackgroundTaskRunner("ScheduledTasks", _logger, _hostingEnvironment);
_scrubberRunner = new BackgroundTaskRunner("LogScrubber", _logger, _hostingEnvironment);
_fileCleanupRunner = new BackgroundTaskRunner("TempFileCleanup", _logger, _hostingEnvironment);
_healthCheckRunner = new BackgroundTaskRunner("HealthCheckNotifier", _logger, _hostingEnvironment);
@@ -138,7 +140,7 @@ namespace Umbraco.Web.Scheduling
{
// ping/keepalive
// on all servers
- var task = new KeepAlive(_keepAliveRunner, DefaultDelayMilliseconds, FiveMinuteMilliseconds, _runtime, keepAliveSettings, _logger);
+ var task = new KeepAlive(_keepAliveRunner, DefaultDelayMilliseconds, FiveMinuteMilliseconds, _runtime, _mainDom, keepAliveSettings, _logger, _serverRegistrar);
_keepAliveRunner.TryAdd(task);
return task;
}
@@ -147,7 +149,7 @@ namespace Umbraco.Web.Scheduling
{
// scheduled publishing/unpublishing
// install on all, will only run on non-replica servers
- var task = new ScheduledPublishing(_publishingRunner, DefaultDelayMilliseconds, OneMinuteMilliseconds, _runtime, _contentService, _umbracoContextFactory, _logger, _serverMessenger);
+ var task = new ScheduledPublishing(_publishingRunner, DefaultDelayMilliseconds, OneMinuteMilliseconds, _runtime, _mainDom, _serverRegistrar, _contentService, _umbracoContextFactory, _logger, _serverMessenger);
_publishingRunner.TryAdd(task);
return task;
}
@@ -173,7 +175,7 @@ namespace Umbraco.Web.Scheduling
}
var periodInMilliseconds = healthCheckSettingsConfig.NotificationSettings.PeriodInHours * 60 * 60 * 1000;
- var task = new HealthCheckNotifier(_healthCheckRunner, delayInMilliseconds, periodInMilliseconds, healthChecks, notifications, _runtime, logger, _healthChecksSettingsConfig);
+ var task = new HealthCheckNotifier(_healthCheckRunner, delayInMilliseconds, periodInMilliseconds, healthChecks, notifications, _mainDom, logger, _healthChecksSettingsConfig, _serverRegistrar, _runtime);
_healthCheckRunner.TryAdd(task);
return task;
}
@@ -182,7 +184,7 @@ namespace Umbraco.Web.Scheduling
{
// log scrubbing
// install on all, will only run on non-replica servers
- var task = new LogScrubber(_scrubberRunner, DefaultDelayMilliseconds, LogScrubber.GetLogScrubbingInterval(), _runtime, _auditService, settings, _scopeProvider, _logger);
+ var task = new LogScrubber(_scrubberRunner, DefaultDelayMilliseconds, LogScrubber.GetLogScrubbingInterval(), _mainDom, _serverRegistrar, _auditService, settings, _scopeProvider, _logger);
_scrubberRunner.TryAdd(task);
return task;
}
@@ -194,7 +196,7 @@ namespace Umbraco.Web.Scheduling
var task = new TempFileCleanup(_fileCleanupRunner, DefaultDelayMilliseconds, OneHourMilliseconds,
new[] { new DirectoryInfo(_ioHelper.MapPath(Constants.SystemDirectories.TempFileUploads)) },
TimeSpan.FromDays(1), //files that are over a day old
- _runtime, _logger);
+ _mainDom, _logger);
_scrubberRunner.TryAdd(task);
return task;
}
diff --git a/src/Umbraco.Infrastructure/Search/BackgroundIndexRebuilder.cs b/src/Umbraco.Infrastructure/Search/BackgroundIndexRebuilder.cs
index 2c964a2723..fa697a4743 100644
--- a/src/Umbraco.Infrastructure/Search/BackgroundIndexRebuilder.cs
+++ b/src/Umbraco.Infrastructure/Search/BackgroundIndexRebuilder.cs
@@ -18,10 +18,10 @@ namespace Umbraco.Web.Search
private readonly IndexRebuilder _indexRebuilder;
private readonly IMainDom _mainDom;
private readonly IProfilingLogger _logger;
- private readonly IHostingEnvironment _hostingEnvironment;
+ private readonly IHostingEnvironmentLifetime _hostingEnvironment;
private static BackgroundTaskRunner _rebuildOnStartupRunner;
- public BackgroundIndexRebuilder(IMainDom mainDom, IProfilingLogger logger, IHostingEnvironment hostingEnvironment, IndexRebuilder indexRebuilder)
+ public BackgroundIndexRebuilder(IMainDom mainDom, IProfilingLogger logger, IHostingEnvironmentLifetime hostingEnvironment, IndexRebuilder indexRebuilder)
{
_mainDom = mainDom;
_logger = logger;
@@ -32,8 +32,6 @@ namespace Umbraco.Web.Search
///
/// Called to rebuild empty indexes on startup
///
- ///
- ///
///
///
public void RebuildIndexes(bool onlyEmptyIndexes, int waitMilliseconds = 0)
diff --git a/src/Umbraco.Infrastructure/Sync/DatabaseServerMessenger.cs b/src/Umbraco.Infrastructure/Sync/DatabaseServerMessenger.cs
index 5a46a37d43..c915013162 100644
--- a/src/Umbraco.Infrastructure/Sync/DatabaseServerMessenger.cs
+++ b/src/Umbraco.Infrastructure/Sync/DatabaseServerMessenger.cs
@@ -28,10 +28,11 @@ namespace Umbraco.Core.Sync
//
public class DatabaseServerMessenger : ServerMessengerBase, IDatabaseServerMessenger
{
- private readonly IRuntimeState _runtime;
+ private readonly IMainDom _mainDom;
private readonly ManualResetEvent _syncIdle;
private readonly object _locko = new object();
private readonly IProfilingLogger _profilingLogger;
+ private readonly IServerRegistrar _serverRegistrar;
private readonly IHostingEnvironment _hostingEnvironment;
private readonly CacheRefresherCollection _cacheRefreshers;
private readonly ISqlContext _sqlContext;
@@ -46,14 +47,15 @@ namespace Umbraco.Core.Sync
public DatabaseServerMessengerOptions Options { get; }
public DatabaseServerMessenger(
- IRuntimeState runtime, IScopeProvider scopeProvider, ISqlContext sqlContext, IProfilingLogger proflog,
+ IMainDom mainDom, IScopeProvider scopeProvider, ISqlContext sqlContext, IProfilingLogger proflog, IServerRegistrar serverRegistrar,
bool distributedEnabled, DatabaseServerMessengerOptions options, IHostingEnvironment hostingEnvironment, CacheRefresherCollection cacheRefreshers)
: base(distributedEnabled)
{
ScopeProvider = scopeProvider ?? throw new ArgumentNullException(nameof(scopeProvider));
_sqlContext = sqlContext;
- _runtime = runtime;
+ _mainDom = mainDom;
_profilingLogger = proflog ?? throw new ArgumentNullException(nameof(proflog));
+ _serverRegistrar = serverRegistrar;
_hostingEnvironment = hostingEnvironment;
_cacheRefreshers = cacheRefreshers;
Logger = proflog;
@@ -126,7 +128,7 @@ namespace Umbraco.Core.Sync
const int weight = 10;
- var registered = _runtime.MainDom.Register(
+ var registered = _mainDom.Register(
() =>
{
lock (_locko)
@@ -262,7 +264,7 @@ namespace Umbraco.Core.Sync
_lastPruned = _lastSync;
- switch (_runtime.ServerRole)
+ switch (_serverRegistrar.GetCurrentServerRole())
{
case ServerRole.Single:
case ServerRole.Master:
diff --git a/src/Umbraco.ModelsBuilder.Embedded/PureLiveModelFactory.cs b/src/Umbraco.ModelsBuilder.Embedded/PureLiveModelFactory.cs
index 5db79de977..3c189cc045 100644
--- a/src/Umbraco.ModelsBuilder.Embedded/PureLiveModelFactory.cs
+++ b/src/Umbraco.ModelsBuilder.Embedded/PureLiveModelFactory.cs
@@ -42,7 +42,7 @@ namespace Umbraco.ModelsBuilder.Embedded
private static readonly string[] OurFiles = { "models.hash", "models.generated.cs", "all.generated.cs", "all.dll.path", "models.err" };
private readonly IModelsBuilderConfig _config;
- private readonly IHostingEnvironment _hostingEnvironment;
+ private readonly IHostingEnvironmentLifetime _hostingLifetime;
private readonly IIOHelper _ioHelper;
private readonly ModelsGenerationError _errors;
@@ -51,12 +51,13 @@ namespace Umbraco.ModelsBuilder.Embedded
IProfilingLogger logger,
IModelsBuilderConfig config,
IHostingEnvironment hostingEnvironment,
+ IHostingEnvironmentLifetime hostingLifetime,
IIOHelper ioHelper)
{
_umbracoServices = umbracoServices;
_logger = logger;
_config = config;
- _hostingEnvironment = hostingEnvironment;
+ _hostingLifetime = hostingLifetime;
_ioHelper = ioHelper;
_errors = new ModelsGenerationError(config, ioHelper);
_ver = 1; // zero is for when we had no version
@@ -64,7 +65,7 @@ namespace Umbraco.ModelsBuilder.Embedded
RazorBuildProvider.CodeGenerationStarted += RazorBuildProvider_CodeGenerationStarted;
- if (!_hostingEnvironment.IsHosted) return;
+ if (!hostingEnvironment.IsHosted) return;
var modelsDirectory = _config.ModelsDirectoryAbsolute(_ioHelper);
if (!Directory.Exists(modelsDirectory))
@@ -73,7 +74,7 @@ namespace Umbraco.ModelsBuilder.Embedded
// BEWARE! if the watcher is not properly released then for some reason the
// BuildManager will start confusing types - using a 'registered object' here
// though we should probably plug into Umbraco's MainDom - which is internal
- _hostingEnvironment.RegisterObject(this);
+ _hostingLifetime.RegisterObject(this);
_watcher = new FileSystemWatcher(modelsDirectory);
_watcher.Changed += WatcherOnChanged;
_watcher.EnableRaisingEvents = true;
@@ -677,7 +678,7 @@ namespace Umbraco.ModelsBuilder.Embedded
{
_watcher.EnableRaisingEvents = false;
_watcher.Dispose();
- _hostingEnvironment.UnregisterObject(this);
+ _hostingLifetime.UnregisterObject(this);
}
#endregion
diff --git a/src/Umbraco.Tests.Common/TestHelperBase.cs b/src/Umbraco.Tests.Common/TestHelperBase.cs
index 536bebee56..76aa38e246 100644
--- a/src/Umbraco.Tests.Common/TestHelperBase.cs
+++ b/src/Umbraco.Tests.Common/TestHelperBase.cs
@@ -12,11 +12,11 @@ using Umbraco.Core.Hosting;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.PublishedContent;
+using Umbraco.Core.Net;
using Umbraco.Core.Persistence;
using Umbraco.Core.Serialization;
using Umbraco.Core.Strings;
using Umbraco.Core.Sync;
-using Umbraco.Net;
using Umbraco.Web;
using Umbraco.Web.Routing;
@@ -31,7 +31,7 @@ namespace Umbraco.Tests.Common
private UriUtility _uriUtility;
private IIOHelper _ioHelper;
- public TestHelperBase(Assembly entryAssembly)
+ protected TestHelperBase(Assembly entryAssembly)
{
SettingsForTests = new SettingsForTests();
MainDom = new SimpleMainDom();
@@ -52,12 +52,8 @@ namespace Umbraco.Tests.Common
return new RuntimeState(
Mock.Of(),
Mock.Of(),
- new Lazy(),
- new Lazy(),
GetUmbracoVersion(),
- GetHostingEnvironment(),
- GetBackOfficeInfo()
- );
+ GetBackOfficeInfo());
}
public abstract IBackOfficeInfo GetBackOfficeInfo();
@@ -132,6 +128,7 @@ namespace Umbraco.Tests.Common
}
public abstract IHostingEnvironment GetHostingEnvironment();
+ public abstract IHostingEnvironmentLifetime GetHostingEnvironmentLifetime();
public abstract IIpResolver GetIpResolver();
diff --git a/src/Umbraco.Tests.Integration/Implementations/HostBuilderExtensions.cs b/src/Umbraco.Tests.Integration/Implementations/HostBuilderExtensions.cs
index 2d86122770..b0b664484b 100644
--- a/src/Umbraco.Tests.Integration/Implementations/HostBuilderExtensions.cs
+++ b/src/Umbraco.Tests.Integration/Implementations/HostBuilderExtensions.cs
@@ -1,31 +1,17 @@
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
-using System;
+using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.SqlClient;
using System.IO;
-using Umbraco.Core.Persistence;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Hosting;
using Umbraco.Tests.Integration.Testing;
-namespace Umbraco.Tests.Integration
+namespace Umbraco.Tests.Integration.Implementations
{
public static class HostBuilderExtensions
{
-
- ///
- /// Ensures the lifetime of the host ends as soon as code executes
- ///
- ///
- ///
- public static IHostBuilder UseTestLifetime(this IHostBuilder hostBuilder)
- {
- hostBuilder.ConfigureServices((context, collection) => collection.AddSingleton());
- return hostBuilder;
- }
-
public static IHostBuilder UseLocalDb(this IHostBuilder hostBuilder, string dbFilePath)
{
// Need to register SqlClient manually
diff --git a/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs b/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs
index 4c37903b0c..f1aa53694c 100644
--- a/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs
+++ b/src/Umbraco.Tests.Integration/Implementations/TestHelper.cs
@@ -8,10 +8,11 @@ using System.Net;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Diagnostics;
+using Umbraco.Core.Hosting;
using Umbraco.Core.Logging;
+using Umbraco.Core.Net;
using Umbraco.Core.Persistence;
using Umbraco.Core.Runtime;
-using Umbraco.Net;
using Umbraco.Tests.Common;
using Umbraco.Web.BackOffice;
using Umbraco.Web.BackOffice.AspNetCore;
@@ -19,11 +20,11 @@ using IHostingEnvironment = Umbraco.Core.Hosting.IHostingEnvironment;
namespace Umbraco.Tests.Integration.Implementations
{
-
public class TestHelper : TestHelperBase
{
private IBackOfficeInfo _backOfficeInfo;
private readonly IHostingEnvironment _hostingEnvironment;
+ private readonly IHostingEnvironmentLifetime _hostingLifetime;
private readonly IIpResolver _ipResolver;
private readonly IWebHostEnvironment _hostEnvironment;
private readonly IHttpContextAccessor _httpContextAccessor;
@@ -40,11 +41,12 @@ namespace Umbraco.Tests.Integration.Implementations
&& x.ContentRootPath == CurrentAssemblyDirectory
&& x.WebRootPath == CurrentAssemblyDirectory); // same folder for now?
- _hostingEnvironment = new AspNetCoreHostingEnvironment(
+ _hostingEnvironment = new TestHostingEnvironment(
SettingsForTests.GetDefaultHostingSettings(),
_hostEnvironment,
- _httpContextAccessor,
- Mock.Of());
+ _httpContextAccessor);
+
+ _hostingLifetime = new AspNetCoreHostingEnvironmentLifetime(Mock.Of());
Logger = new ProfilingLogger(new ConsoleLogger(new MessageTemplates()), Profiler);
}
@@ -75,7 +77,9 @@ namespace Umbraco.Tests.Integration.Implementations
}
public override IHostingEnvironment GetHostingEnvironment() => _hostingEnvironment;
+ public override IHostingEnvironmentLifetime GetHostingEnvironmentLifetime() => _hostingLifetime;
public override IIpResolver GetIpResolver() => _ipResolver;
+
}
}
diff --git a/src/Umbraco.Tests.Integration/Implementations/TestHostingEnvironment.cs b/src/Umbraco.Tests.Integration/Implementations/TestHostingEnvironment.cs
new file mode 100644
index 0000000000..491b7e5480
--- /dev/null
+++ b/src/Umbraco.Tests.Integration/Implementations/TestHostingEnvironment.cs
@@ -0,0 +1,23 @@
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
+using Umbraco.Core.Configuration;
+using Umbraco.Web.BackOffice.AspNetCore;
+
+namespace Umbraco.Tests.Integration.Implementations
+{
+
+ public class TestHostingEnvironment : AspNetCoreHostingEnvironment, Umbraco.Core.Hosting.IHostingEnvironment
+ {
+ public TestHostingEnvironment(IHostingSettings hostingSettings, IWebHostEnvironment webHostEnvironment, IHttpContextAccessor httpContextAccessor) : base(hostingSettings, webHostEnvironment, httpContextAccessor)
+ {
+ }
+
+ ///
+ /// Override for tests since we are not hosted
+ ///
+ ///
+ /// This is specifically used by IOHelper and we want this to return false so that the root path is manually calcualted which is what we want for tests.
+ ///
+ bool Umbraco.Core.Hosting.IHostingEnvironment.IsHosted { get; } = false;
+ }
+}
diff --git a/src/Umbraco.Tests.Integration/Implementations/TestLifetime.cs b/src/Umbraco.Tests.Integration/Implementations/TestLifetime.cs
index 063644490b..a18360eff9 100644
--- a/src/Umbraco.Tests.Integration/Implementations/TestLifetime.cs
+++ b/src/Umbraco.Tests.Integration/Implementations/TestLifetime.cs
@@ -1,8 +1,8 @@
-using Microsoft.Extensions.Hosting;
-using System.Threading;
+using System.Threading;
using System.Threading.Tasks;
+using Microsoft.Extensions.Hosting;
-namespace Umbraco.Tests.Integration
+namespace Umbraco.Tests.Integration.Implementations
{
///
/// Ensures the host lifetime ends as soon as code execution is done
diff --git a/src/Umbraco.Tests.Integration/RuntimeTests.cs b/src/Umbraco.Tests.Integration/RuntimeTests.cs
index dae4d0cbb8..c9e0e94481 100644
--- a/src/Umbraco.Tests.Integration/RuntimeTests.cs
+++ b/src/Umbraco.Tests.Integration/RuntimeTests.cs
@@ -10,6 +10,7 @@ using NUnit.Framework;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
+using Microsoft.AspNetCore.Builder;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Composing.LightInject;
@@ -46,27 +47,36 @@ namespace Umbraco.Tests.Integration
/// Manually configure the containers/dependencies and call Boot on Core runtime
///
[Test]
- public void BootCoreRuntime()
+ public void Boot_Core_Runtime()
{
// LightInject / Umbraco
var container = UmbracoServiceProviderFactory.CreateServiceContainer();
var serviceProviderFactory = new UmbracoServiceProviderFactory(container);
var umbracoContainer = serviceProviderFactory.GetContainer();
- // Create the core runtime
+ // Special case since we are not using the Generic Host, we need to manually add an AspNetCore service to the container
+ umbracoContainer.Register(x => Mock.Of());
+
var testHelper = new TestHelper();
+
+ // Create the core runtime
var coreRuntime = new CoreRuntime(testHelper.GetConfigs(), testHelper.GetUmbracoVersion(),
testHelper.IOHelper, testHelper.Logger, testHelper.Profiler, testHelper.UmbracoBootPermissionChecker,
testHelper.GetHostingEnvironment(), testHelper.GetBackOfficeInfo(), testHelper.DbProviderFactoryCreator,
testHelper.MainDom, testHelper.GetTypeFinder());
- // boot it!
- var factory = coreRuntime.Boot(umbracoContainer);
+ // boot it!
+ var factory = coreRuntime.Configure(umbracoContainer);
Assert.IsTrue(coreRuntime.MainDom.IsMainDom);
Assert.IsNull(coreRuntime.State.BootFailedException);
Assert.AreEqual(RuntimeLevel.Install, coreRuntime.State.Level);
Assert.IsTrue(MyComposer.IsComposed);
+ Assert.IsFalse(MyComponent.IsInit);
+ Assert.IsFalse(MyComponent.IsTerminated);
+
+ coreRuntime.Start();
+
Assert.IsTrue(MyComponent.IsInit);
Assert.IsFalse(MyComponent.IsTerminated);
@@ -78,7 +88,7 @@ namespace Umbraco.Tests.Integration
}
///
- /// Calling AddUmbracoCore to configure the container and boot the core runtime within a generic host
+ /// Calling AddUmbracoCore to configure the container
///
[Test]
public async Task AddUmbracoCore()
@@ -99,22 +109,106 @@ namespace Umbraco.Tests.Integration
});
var host = await hostBuilder.StartAsync();
+ var app = new ApplicationBuilder(host.Services);
// assert results
- var runtimeState = umbracoContainer.GetInstance();
- var mainDom = umbracoContainer.GetInstance();
+ var runtimeState = app.ApplicationServices.GetRequiredService();
+ var mainDom = app.ApplicationServices.GetRequiredService();
+
+ Assert.IsFalse(mainDom.IsMainDom); // We haven't "Started" the runtime yet
+ Assert.IsNull(runtimeState.BootFailedException);
+ Assert.AreEqual(RuntimeLevel.Install, runtimeState.Level);
+ Assert.IsFalse(MyComponent.IsInit); // We haven't "Started" the runtime yet
+
+ await host.StopAsync();
+
+ Assert.IsFalse(MyComponent.IsTerminated); // we didn't "Start" the runtime so nothing was registered for shutdown
+ }
+
+ ///
+ /// Calling AddUmbracoCore to configure the container and UseUmbracoCore to start the runtime
+ ///
+ ///
+ [Test]
+ public async Task UseUmbracoCore()
+ {
+ var umbracoContainer = GetUmbracoContainer(out var serviceProviderFactory);
+ var testHelper = new TestHelper();
+
+ var hostBuilder = new HostBuilder()
+ .UseUmbraco(serviceProviderFactory)
+ .ConfigureServices((hostContext, services) =>
+ {
+ AddRequiredNetCoreServices(services, testHelper);
+
+ // Add it!
+ services.AddUmbracoConfiguration();
+ services.AddUmbracoCore(umbracoContainer, GetType().Assembly);
+ });
+
+ var host = await hostBuilder.StartAsync();
+ var app = new ApplicationBuilder(host.Services);
+
+ app.UseUmbracoCore();
+
+
+ // assert results
+ var runtimeState = app.ApplicationServices.GetRequiredService();
+ var mainDom = app.ApplicationServices.GetRequiredService();
Assert.IsTrue(mainDom.IsMainDom);
Assert.IsNull(runtimeState.BootFailedException);
Assert.AreEqual(RuntimeLevel.Install, runtimeState.Level);
Assert.IsTrue(MyComponent.IsInit);
- Assert.IsFalse(MyComponent.IsTerminated);
await host.StopAsync();
Assert.IsTrue(MyComponent.IsTerminated);
}
+ [Test]
+ public async Task Install_Database()
+ {
+ var umbracoContainer = GetUmbracoContainer(out var serviceProviderFactory);
+ var testHelper = new TestHelper();
+
+ var hostBuilder = new HostBuilder()
+ //TODO: Need to have a configured umb version for the runtime state
+ .UseLocalDb(Path.Combine(testHelper.CurrentAssemblyDirectory, "LocalDb"))
+ .UseUmbraco(serviceProviderFactory)
+ .ConfigureServices((hostContext, services) =>
+ {
+ AddRequiredNetCoreServices(services, testHelper);
+
+ // Add it!
+ services.AddUmbracoConfiguration();
+ services.AddUmbracoCore(umbracoContainer, GetType().Assembly);
+ });
+
+ var host = await hostBuilder.StartAsync();
+ var app = new ApplicationBuilder(host.Services);
+
+ app.UseUmbracoCore();
+
+
+ var runtimeState = (RuntimeState)app.ApplicationServices.GetRequiredService();
+ Assert.AreEqual(RuntimeLevel.Install, runtimeState.Level);
+
+ var dbBuilder = app.ApplicationServices.GetRequiredService();
+ Assert.IsNotNull(dbBuilder);
+
+ var canConnect = dbBuilder.CanConnectToDatabase;
+ Assert.IsTrue(canConnect);
+
+ var dbResult = dbBuilder.CreateSchemaAndData();
+ Assert.IsTrue(dbResult.Success);
+
+ // TODO: Get this to work ... but to do that we need to mock or pass in a current umbraco version
+ //var dbFactory = app.ApplicationServices.GetRequiredService();
+ //var profilingLogger = app.ApplicationServices.GetRequiredService();
+ //runtimeState.DetermineRuntimeLevel(dbFactory, profilingLogger);
+ //Assert.AreEqual(RuntimeLevel.Run, runtimeState.Level);
+ }
[Ignore("This test just shows that resolving services from the container before the host is done resolves 2 different instances")]
[Test]
@@ -128,6 +222,8 @@ namespace Umbraco.Tests.Integration
.UseUmbraco(serviceProviderFactory)
.ConfigureServices((hostContext, services) =>
{
+ // TODO: Try to re-register the service as a callback and see if it resolves to the same instance
+
lifetime1 = services.BuildServiceProvider().GetRequiredService();
});
@@ -141,46 +237,6 @@ namespace Umbraco.Tests.Integration
}
- [Test]
- public async Task UseUmbracoCore()
- {
- var umbracoContainer = GetUmbracoContainer(out var serviceProviderFactory);
- var testHelper = new TestHelper();
-
- var hostBuilder = new HostBuilder()
- //TODO: Need to have a configured umb version for the runtime state
- .UseLocalDb(Path.Combine(testHelper.CurrentAssemblyDirectory, "LocalDb"))
- //.UseTestLifetime()
- .UseUmbraco(serviceProviderFactory)
- .ConfigureServices((hostContext, services) =>
- {
- AddRequiredNetCoreServices(services, testHelper);
-
- // Add it!
- services.AddUmbracoConfiguration();
- services.AddUmbracoCore(umbracoContainer, GetType().Assembly);
- });
-
- var host = await hostBuilder.StartAsync();
-
- var runtimeState = (RuntimeState)umbracoContainer.GetInstance();
- Assert.AreEqual(RuntimeLevel.Install, runtimeState.Level);
-
- var dbBuilder = umbracoContainer.GetInstance();
- Assert.IsNotNull(dbBuilder);
-
- var canConnect = dbBuilder.CanConnectToDatabase;
- Assert.IsTrue(canConnect);
-
- var dbResult = dbBuilder.CreateSchemaAndData();
- Assert.IsTrue(dbResult.Success);
-
- var dbFactory = umbracoContainer.GetInstance();
- var profilingLogger = umbracoContainer.GetInstance();
- runtimeState.DetermineRuntimeLevel(dbFactory, profilingLogger);
- Assert.AreEqual(RuntimeLevel.Run, runtimeState.Level);
- }
-
private LightInjectContainer GetUmbracoContainer(out UmbracoServiceProviderFactory serviceProviderFactory)
{
var container = new ServiceContainer(ContainerOptions.Default.Clone().WithMicrosoftSettings().WithAspNetCoreSettings());
@@ -189,9 +245,15 @@ namespace Umbraco.Tests.Integration
return umbracoContainer;
}
+ ///
+ /// These services need to be manually added because they do not get added by the generic host
+ ///
+ ///
+ ///
private void AddRequiredNetCoreServices(IServiceCollection services, TestHelper testHelper)
{
services.AddSingleton(x => testHelper.GetHttpContextAccessor());
+ // the generic host does add IHostEnvironment but not this one because we are not actually in a web context
services.AddSingleton(x => testHelper.GetWebHostEnvironment());
}
diff --git a/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlPublishedSnapshotService.cs b/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlPublishedSnapshotService.cs
index 609dcd98b8..5eb57b6ca6 100644
--- a/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlPublishedSnapshotService.cs
+++ b/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlPublishedSnapshotService.cs
@@ -41,6 +41,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
private readonly IEntityXmlSerializer _entitySerializer;
private readonly IVariationContextAccessor _variationContextAccessor;
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
+ private readonly IHostingEnvironmentLifetime _hostingLifetime;
private readonly IHostingEnvironment _hostingEnvironment;
#region Constructors
@@ -57,6 +58,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
ILogger logger,
IGlobalSettings globalSettings,
IHostingEnvironment hostingEnvironment,
+ IHostingEnvironmentLifetime hostingLifetime,
IShortStringHelper shortStringHelper,
ISiteDomainHelper siteDomainHelper,
IEntityXmlSerializer entitySerializer,
@@ -67,7 +69,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
publishedSnapshotAccessor, variationContextAccessor, umbracoContextAccessor,
documentRepository, mediaRepository, memberRepository,
defaultCultureAccessor,
- logger, globalSettings, hostingEnvironment, shortStringHelper, siteDomainHelper, entitySerializer, null, mainDom, testing, enableRepositoryEvents)
+ logger, globalSettings, hostingEnvironment, hostingLifetime, shortStringHelper, siteDomainHelper, entitySerializer, null, mainDom, testing, enableRepositoryEvents)
{
_umbracoContextAccessor = umbracoContextAccessor;
}
@@ -84,6 +86,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
ILogger logger,
IGlobalSettings globalSettings,
IHostingEnvironment hostingEnvironment,
+ IHostingEnvironmentLifetime hostingLifetime,
IShortStringHelper shortStringHelper,
ISiteDomainHelper siteDomainHelper,
IEntityXmlSerializer entitySerializer,
@@ -99,7 +102,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
_xmlStore = new XmlStore(serviceContext.ContentTypeService, serviceContext.ContentService, scopeProvider, _routesCache,
_contentTypeCache, publishedSnapshotAccessor, mainDom, testing, enableRepositoryEvents,
- documentRepository, mediaRepository, memberRepository, globalSettings, entitySerializer, hostingEnvironment, shortStringHelper);
+ documentRepository, mediaRepository, memberRepository, entitySerializer, hostingEnvironment, hostingLifetime, shortStringHelper);
_domainService = serviceContext.DomainService;
_memberService = serviceContext.MemberService;
@@ -113,6 +116,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
_siteDomainHelper = siteDomainHelper;
_entitySerializer = entitySerializer;
_hostingEnvironment = hostingEnvironment;
+ _hostingLifetime = hostingLifetime;
}
public override void Dispose()
diff --git a/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlStore.cs b/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlStore.cs
index 238da68370..b051682ed7 100644
--- a/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlStore.cs
+++ b/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlStore.cs
@@ -45,9 +45,8 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
private readonly IDocumentRepository _documentRepository;
private readonly IMediaRepository _mediaRepository;
private readonly IMemberRepository _memberRepository;
- private readonly IGlobalSettings _globalSettings;
private readonly IEntityXmlSerializer _entitySerializer;
- private readonly IHostingEnvironment _hostingEnvironment;
+ private readonly IHostingEnvironmentLifetime _hostingLifetime;
private readonly IShortStringHelper _shortStringHelper;
private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor;
private readonly PublishedContentTypeCache _contentTypeCache;
@@ -58,7 +57,6 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
private XmlStoreFilePersister _persisterTask;
private volatile bool _released;
- private bool _withRepositoryEvents;
#region Constructors
@@ -67,8 +65,8 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
///
/// The default constructor will boot the cache, load data from file or database, /// wire events in order to manage changes, etc.
public XmlStore(IContentTypeService contentTypeService, IContentService contentService, IScopeProvider scopeProvider, RoutesCache routesCache, PublishedContentTypeCache contentTypeCache,
- IPublishedSnapshotAccessor publishedSnapshotAccessor, MainDom mainDom, IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository, IGlobalSettings globalSettings, IEntityXmlSerializer entitySerializer, IHostingEnvironment hostingEnvironment, IShortStringHelper shortStringHelper)
- : this(contentTypeService, contentService, scopeProvider, routesCache, contentTypeCache, publishedSnapshotAccessor, mainDom, false, false, documentRepository, mediaRepository, memberRepository, globalSettings, entitySerializer, hostingEnvironment, shortStringHelper)
+ IPublishedSnapshotAccessor publishedSnapshotAccessor, MainDom mainDom, IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository, IEntityXmlSerializer entitySerializer, IHostingEnvironment hostingEnvironment, IHostingEnvironmentLifetime hostingLifetime, IShortStringHelper shortStringHelper)
+ : this(contentTypeService, contentService, scopeProvider, routesCache, contentTypeCache, publishedSnapshotAccessor, mainDom, false, false, documentRepository, mediaRepository, memberRepository, entitySerializer, hostingEnvironment, hostingLifetime, shortStringHelper)
{ }
// internal for unit tests
@@ -76,7 +74,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
// TODO: er, we DO have a DB?
internal XmlStore(IContentTypeService contentTypeService, IContentService contentService, IScopeProvider scopeProvider, RoutesCache routesCache, PublishedContentTypeCache contentTypeCache,
IPublishedSnapshotAccessor publishedSnapshotAccessor, MainDom mainDom,
- bool testing, bool enableRepositoryEvents, IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository, IGlobalSettings globalSettings, IEntityXmlSerializer entitySerializer, IHostingEnvironment hostingEnvironment, IShortStringHelper shortStringHelper)
+ bool testing, bool enableRepositoryEvents, IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository, IEntityXmlSerializer entitySerializer, IHostingEnvironment hostingEnvironment, IHostingEnvironmentLifetime hostingLifetime, IShortStringHelper shortStringHelper)
{
if (testing == false)
EnsureConfigurationIsValid();
@@ -90,12 +88,11 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
_documentRepository = documentRepository;
_mediaRepository = mediaRepository;
_memberRepository = memberRepository;
- _globalSettings = globalSettings;
_entitySerializer = entitySerializer;
- _hostingEnvironment = hostingEnvironment;
+ _hostingLifetime = hostingLifetime;
_shortStringHelper = shortStringHelper;
- _xmlFileName = TestHelper.IOHelper.MapPath(SystemFiles.GetContentCacheXml(_hostingEnvironment));
+ _xmlFileName = TestHelper.IOHelper.MapPath(SystemFiles.GetContentCacheXml(hostingEnvironment));
if (testing)
{
@@ -150,7 +147,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
LongRunning = true,
KeepAlive = true,
Hosted = false // main domain will take care of stopping the runner (see below)
- }, logger, _hostingEnvironment);
+ }, logger, _hostingLifetime);
// create (and add to runner)
_persisterTask = new XmlStoreFilePersister(runner, this, logger);
@@ -207,7 +204,6 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
MediaTypeService.ScopedRefreshedEntity += OnMediaTypeRefreshedEntity;
MemberTypeService.ScopedRefreshedEntity += OnMemberTypeRefreshedEntity;
- _withRepositoryEvents = true;
}
private void ClearEvents()
@@ -226,7 +222,6 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
MediaTypeService.ScopedRefreshedEntity -= OnMediaTypeRefreshedEntity;
MemberTypeService.ScopedRefreshedEntity -= OnMemberTypeRefreshedEntity;
- _withRepositoryEvents = false;
}
private void LazyInitializeContent()
diff --git a/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs b/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs
index 561a6d945e..f9de3579c2 100644
--- a/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs
+++ b/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs
@@ -32,8 +32,7 @@ namespace Umbraco.Tests.Routing
//create the module
var logger = Mock.Of();
var globalSettings = TestObjects.GetGlobalSettings();
- var runtime = new RuntimeState(logger, globalSettings,
- new Lazy(), new Lazy(), UmbracoVersion, HostingEnvironment, BackOfficeInfo);
+ var runtime = new RuntimeState(logger, globalSettings, UmbracoVersion, BackOfficeInfo);
_module = new UmbracoInjectedModule
(
diff --git a/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs b/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs
index 92ab825ee2..44481666bc 100644
--- a/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs
+++ b/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs
@@ -146,31 +146,31 @@ namespace Umbraco.Tests.Runtimes
}
*/
- // because we don't even have the core runtime component,
- // there are a few required stuff that we need to compose
- public override void Compose(Composition composition)
- {
- base.Compose(composition);
+ //// because we don't even have the core runtime component,
+ //// there are a few required stuff that we need to compose
+ //public override void Compose(Composition composition)
+ //{
+ // base.Compose(composition);
- var scopeProvider = Mock.Of();
- Mock.Get(scopeProvider)
- .Setup(x => x.CreateScope(
- It.IsAny(),
- It.IsAny(),
- It.IsAny(),
- It.IsAny(),
- It.IsAny(),
- It.IsAny()))
- .Returns(Mock.Of());
+ // var scopeProvider = Mock.Of();
+ // Mock.Get(scopeProvider)
+ // .Setup(x => x.CreateScope(
+ // It.IsAny(),
+ // It.IsAny(),
+ // It.IsAny(),
+ // It.IsAny(),
+ // It.IsAny(),
+ // It.IsAny()))
+ // .Returns(Mock.Of());
- composition.RegisterUnique(scopeProvider);
- }
+ // composition.RegisterUnique(scopeProvider);
+ //}
private IMainDom _mainDom;
- public override IFactory Boot(IRegister container)
+ public override IFactory Configure(IRegister container)
{
- var factory = base.Boot(container);
+ var factory = base.Configure(container);
_mainDom = factory.GetInstance();
return factory;
}
diff --git a/src/Umbraco.Tests/Runtimes/StandaloneTests.cs b/src/Umbraco.Tests/Runtimes/StandaloneTests.cs
index 99a5352a17..f167aafb89 100644
--- a/src/Umbraco.Tests/Runtimes/StandaloneTests.cs
+++ b/src/Umbraco.Tests/Runtimes/StandaloneTests.cs
@@ -72,7 +72,7 @@ namespace Umbraco.Tests.Runtimes
var mainDom = new SimpleMainDom();
var umbracoVersion = TestHelper.GetUmbracoVersion();
var backOfficeInfo = TestHelper.GetBackOfficeInfo();
- var runtimeState = new RuntimeState(logger, null, new Lazy(() => mainDom), new Lazy(() => factory.GetInstance()), umbracoVersion, hostingEnvironment, backOfficeInfo);
+ var runtimeState = new RuntimeState(logger, null, umbracoVersion, backOfficeInfo);
var configs = TestHelper.GetConfigs();
var variationContextAccessor = TestHelper.VariationContextAccessor;
@@ -84,7 +84,6 @@ namespace Umbraco.Tests.Runtimes
// create the core runtime and have it compose itself
var coreRuntime = new CoreRuntime(configs, umbracoVersion, ioHelper, logger, profiler, new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom, typeFinder);
- coreRuntime.Compose(composition);
// determine actual runtime level
runtimeState.DetermineRuntimeLevel(databaseFactory, logger);
@@ -279,7 +278,6 @@ namespace Umbraco.Tests.Runtimes
// create the core runtime and have it compose itself
var coreRuntime = new CoreRuntime(configs, umbracoVersion, ioHelper, logger, profiler, new AspNetUmbracoBootPermissionChecker(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom, typeFinder);
- coreRuntime.Compose(composition);
// get the components
// all of them?
diff --git a/src/Umbraco.Tests/Scheduling/BackgroundTaskRunnerTests.cs b/src/Umbraco.Tests/Scheduling/BackgroundTaskRunnerTests.cs
index f10b141916..18eb3d19a4 100644
--- a/src/Umbraco.Tests/Scheduling/BackgroundTaskRunnerTests.cs
+++ b/src/Umbraco.Tests/Scheduling/BackgroundTaskRunnerTests.cs
@@ -19,13 +19,13 @@ namespace Umbraco.Tests.Scheduling
public class BackgroundTaskRunnerTests
{
private ILogger _logger;
- private IHostingEnvironment _hostingEnvironment;
+ private IHostingEnvironmentLifetime _hostingEnvironment;
[OneTimeSetUp]
public void InitializeFixture()
{
_logger = new ConsoleLogger(new MessageTemplates());
- _hostingEnvironment = TestHelper.GetHostingEnvironment();
+ _hostingEnvironment = TestHelper.GetHostingEnvironmentLifetime();
}
[Test]
@@ -934,7 +934,7 @@ namespace Umbraco.Tests.Scheduling
[Test]
public void SourceTaskTest()
{
- var runner = new BackgroundTaskRunner(new BackgroundTaskRunnerOptions { KeepAlive = true, LongRunning = true }, _logger, TestHelper.GetHostingEnvironment());
+ var runner = new BackgroundTaskRunner(new BackgroundTaskRunnerOptions { KeepAlive = true, LongRunning = true }, _logger, TestHelper.GetHostingEnvironmentLifetime());
var task = new SourceTask();
runner.Add(task);
diff --git a/src/Umbraco.Tests/Scheduling/BackgroundTaskRunnerTests2.cs b/src/Umbraco.Tests/Scheduling/BackgroundTaskRunnerTests2.cs
index c65c7e3efb..01169abce2 100644
--- a/src/Umbraco.Tests/Scheduling/BackgroundTaskRunnerTests2.cs
+++ b/src/Umbraco.Tests/Scheduling/BackgroundTaskRunnerTests2.cs
@@ -22,7 +22,7 @@ namespace Umbraco.Tests.Scheduling
public async Task ThreadResumeIssue()
{
var logger = new DebugDiagnosticsLogger(new MessageTemplates());
- var runner = new BackgroundTaskRunner(new BackgroundTaskRunnerOptions { KeepAlive = true, LongRunning = true }, logger, TestHelper.GetHostingEnvironment());
+ var runner = new BackgroundTaskRunner(new BackgroundTaskRunnerOptions { KeepAlive = true, LongRunning = true }, logger, TestHelper.GetHostingEnvironmentLifetime());
var work = new ThreadResumeIssueWorkItem();
runner.Add(work);
@@ -77,7 +77,7 @@ namespace Umbraco.Tests.Scheduling
public async Task DebuggerInterferenceIssue()
{
var logger = new DebugDiagnosticsLogger(new MessageTemplates());
- var runner = new BackgroundTaskRunner(new BackgroundTaskRunnerOptions { KeepAlive = true, LongRunning = true }, logger, TestHelper.GetHostingEnvironment());
+ var runner = new BackgroundTaskRunner(new BackgroundTaskRunnerOptions { KeepAlive = true, LongRunning = true }, logger, TestHelper.GetHostingEnvironmentLifetime());
var taskCompleted = false;
runner.TaskCompleted += (sender, args) =>
{
diff --git a/src/Umbraco.Tests/TestHelpers/TestHelper.cs b/src/Umbraco.Tests/TestHelpers/TestHelper.cs
index 05d4de6e23..54cbec46e9 100644
--- a/src/Umbraco.Tests/TestHelpers/TestHelper.cs
+++ b/src/Umbraco.Tests/TestHelpers/TestHelper.cs
@@ -21,12 +21,12 @@ using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Entities;
using Umbraco.Core.Models.PublishedContent;
+using Umbraco.Core.Net;
using Umbraco.Core.Persistence;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Serialization;
using Umbraco.Core.Services;
using Umbraco.Core.Strings;
-using Umbraco.Net;
using Umbraco.Tests.Common;
using Umbraco.Web;
using Umbraco.Web.Hosting;
@@ -40,7 +40,7 @@ namespace Umbraco.Tests.TestHelpers
///
public static class TestHelper
{
- private static TestHelperInternal _testHelperInternal = new TestHelperInternal();
+ private static readonly TestHelperInternal _testHelperInternal = new TestHelperInternal();
private class TestHelperInternal : TestHelperBase
{
public TestHelperInternal() : base(typeof(TestHelperInternal).Assembly)
@@ -62,6 +62,9 @@ namespace Umbraco.Tests.TestHelpers
public override IHostingEnvironment GetHostingEnvironment()
=> new AspNetHostingEnvironment(SettingsForTests.GetDefaultHostingSettings());
+ public override IHostingEnvironmentLifetime GetHostingEnvironmentLifetime()
+ => new AspNetHostingLifetime();
+
public override IIpResolver GetIpResolver()
=> new AspNetIpResolver();
}
@@ -320,6 +323,8 @@ namespace Umbraco.Tests.TestHelpers
public static IHostingEnvironment GetHostingEnvironment() => _testHelperInternal.GetHostingEnvironment();
+ public static IHostingEnvironmentLifetime GetHostingEnvironmentLifetime() => _testHelperInternal.GetHostingEnvironmentLifetime();
+
public static IIpResolver GetIpResolver() => _testHelperInternal.GetIpResolver();
public static IRequestCache GetRequestCache() => _testHelperInternal.GetRequestCache();
diff --git a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs
index 5cf2c7b6bd..fbfada118a 100644
--- a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs
+++ b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs
@@ -265,6 +265,7 @@ namespace Umbraco.Tests.TestHelpers
Logger,
Factory.GetInstance(),
HostingEnvironment,
+ HostingLifetime,
ShortStringHelper,
new SiteDomainHelper(),
Factory.GetInstance(),
diff --git a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs
index ca36a6049e..9222f7e4ab 100644
--- a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs
+++ b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs
@@ -51,10 +51,10 @@ using Umbraco.Web.Templates;
using Umbraco.Web.PropertyEditors;
using Umbraco.Core.Dictionary;
using Umbraco.Core.Models;
+using Umbraco.Core.Net;
using Umbraco.Core.Request;
using Umbraco.Core.Security;
using Umbraco.Core.Services;
-using Umbraco.Net;
using Umbraco.Tests.LegacyXmlPublishedCache;
using Umbraco.Web.AspNet;
using Umbraco.Web.Install;
@@ -140,6 +140,7 @@ namespace Umbraco.Tests.Testing
protected virtual IProfilingLogger ProfilingLogger => Factory.GetInstance();
protected IHostingEnvironment HostingEnvironment { get; } = new AspNetHostingEnvironment(TestHelpers.SettingsForTests.GetDefaultHostingSettings());
+ protected IHostingEnvironmentLifetime HostingLifetime { get; } = new AspNetHostingLifetime();
protected IIpResolver IpResolver => Factory.GetInstance();
protected IBackOfficeInfo BackOfficeInfo => Factory.GetInstance();
protected AppCaches AppCaches => Factory.GetInstance();
diff --git a/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs b/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs
index 5e5197a28a..c5e9556d05 100644
--- a/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs
+++ b/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs
@@ -423,6 +423,7 @@ namespace Umbraco.Tests.Web.Mvc
new TestDefaultCultureAccessor(),
Current.Logger, TestObjects.GetGlobalSettings(),
TestHelper.GetHostingEnvironment(),
+ TestHelper.GetHostingEnvironmentLifetime(),
ShortStringHelper,
new SiteDomainHelper(),
Factory.GetInstance(),
diff --git a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreComposer.cs b/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreComposer.cs
new file mode 100644
index 0000000000..e85f3cb3f9
--- /dev/null
+++ b/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreComposer.cs
@@ -0,0 +1,27 @@
+using Microsoft.AspNetCore.Http;
+using Umbraco.Core;
+using Umbraco.Core.Composing;
+using Umbraco.Core.Hosting;
+using Umbraco.Core.Net;
+using Umbraco.Core.Runtime;
+
+namespace Umbraco.Web.BackOffice.AspNetCore
+{
+ ///
+ /// Adds/replaces AspNetCore specific services
+ ///
+ [ComposeBefore(typeof(ICoreComposer))]
+ [ComposeAfter(typeof(CoreInitialComposer))]
+ public class AspNetCoreComposer : IComposer
+ {
+ public void Compose(Composition composition)
+ {
+ // AspNetCore specific services
+ composition.RegisterUnique();
+
+ // Our own netcore implementations
+ composition.RegisterUnique();
+ composition.RegisterUnique();
+ }
+ }
+}
diff --git a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreHostingEnvironment.cs b/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreHostingEnvironment.cs
index 00bc894b0d..6f1298918d 100644
--- a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreHostingEnvironment.cs
+++ b/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreHostingEnvironment.cs
@@ -1,11 +1,8 @@
using System;
-using System.Collections.Concurrent;
-using System.Diagnostics;
+using System.Globalization;
using System.IO;
-using System.Threading;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.Hosting;
using Umbraco.Core;
using Umbraco.Core.Configuration;
@@ -13,30 +10,29 @@ namespace Umbraco.Web.BackOffice.AspNetCore
{
public class AspNetCoreHostingEnvironment : Umbraco.Core.Hosting.IHostingEnvironment
{
- private readonly ConcurrentDictionary _registeredObjects =
- new ConcurrentDictionary();
+
private readonly IHostingSettings _hostingSettings;
private readonly IWebHostEnvironment _webHostEnvironment;
private readonly IHttpContextAccessor _httpContextAccessor;
- private readonly IHostApplicationLifetime _hostApplicationLifetime;
+
private string _localTempPath;
- public AspNetCoreHostingEnvironment(IHostingSettings hostingSettings, IWebHostEnvironment webHostEnvironment, IHttpContextAccessor httpContextAccessor, IHostApplicationLifetime hostHostApplicationLifetime)
+ public AspNetCoreHostingEnvironment(IHostingSettings hostingSettings, IWebHostEnvironment webHostEnvironment, IHttpContextAccessor httpContextAccessor)
{
_hostingSettings = hostingSettings ?? throw new ArgumentNullException(nameof(hostingSettings));
_webHostEnvironment = webHostEnvironment;
_httpContextAccessor = httpContextAccessor;
- _hostApplicationLifetime = hostHostApplicationLifetime;
SiteName = webHostEnvironment.ApplicationName;
ApplicationId = AppDomain.CurrentDomain.Id.ToString();
ApplicationPhysicalPath = webHostEnvironment.ContentRootPath;
ApplicationVirtualPath = "/"; //TODO how to find this, This is a server thing, not application thing.
- IISVersion = new Version(0, 0); // TODO not necessary IIS
+ IISVersion = new Version(0, 0); // TODO not necessary IIS
IsDebugMode = _hostingSettings.DebugMode;
}
+
public bool IsHosted { get; } = true;
public string SiteName { get; }
public string ApplicationId { get; }
@@ -56,7 +52,10 @@ namespace Umbraco.Web.BackOffice.AspNetCore
switch (_hostingSettings.LocalTempStorageLocation)
{
case LocalTempStorage.AspNetTemp:
- return _localTempPath = System.IO.Path.Combine(Path.GetTempPath(),ApplicationId, "UmbracoData");
+
+ // TODO: I don't think this is correct? but also we probably can remove AspNetTemp as an option entirely
+ // since this is legacy and we shouldn't use it
+ return _localTempPath = System.IO.Path.Combine(Path.GetTempPath(), ApplicationId, "UmbracoData");
case LocalTempStorage.EnvironmentTemp:
@@ -84,8 +83,11 @@ namespace Umbraco.Web.BackOffice.AspNetCore
}
}
- // TODO: This may need to take into account ~/ paths which means the ApplicationVirtualPath and is this the content root or web root?
- public string MapPath(string path) => Path.Combine(_webHostEnvironment.WebRootPath, path);
+ public string MapPath(string path)
+ {
+ var newPath = path.TrimStart('~', '/').Replace('/', Path.DirectorySeparatorChar);
+ return Path.Combine(_webHostEnvironment.WebRootPath, newPath);
+ }
// TODO: Need to take into account 'root' here
public string ToAbsolute(string virtualPath, string root)
@@ -101,43 +103,7 @@ namespace Umbraco.Web.BackOffice.AspNetCore
return applicationPath.Add(segment).Value;
}
- public void RegisterObject(IRegisteredObject registeredObject)
- {
- var wrapped = new RegisteredObjectWrapper(registeredObject);
- if (!_registeredObjects.TryAdd(registeredObject, wrapped))
- {
- throw new InvalidOperationException("Could not register object");
- }
-
- var cancellationTokenRegistration = _hostApplicationLifetime.ApplicationStopping.Register(() => wrapped.Stop(true));
- wrapped.CancellationTokenRegistration = cancellationTokenRegistration;
- }
-
- public void UnregisterObject(IRegisteredObject registeredObject)
- {
- if (_registeredObjects.TryGetValue(registeredObject, out var wrapped))
- {
- wrapped.CancellationTokenRegistration.Unregister();
- }
- }
-
-
- private class RegisteredObjectWrapper
- {
- private readonly IRegisteredObject _inner;
-
- public RegisteredObjectWrapper(IRegisteredObject inner)
- {
- _inner = inner;
- }
-
- public CancellationTokenRegistration CancellationTokenRegistration { get; set; }
-
- public void Stop(bool immediate)
- {
- _inner.Stop(immediate);
- }
- }
+
}
diff --git a/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreHostingEnvironmentShutdown.cs b/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreHostingEnvironmentShutdown.cs
new file mode 100644
index 0000000000..3726e50e3b
--- /dev/null
+++ b/src/Umbraco.Web.BackOffice/AspNetCore/AspNetCoreHostingEnvironmentShutdown.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Collections.Concurrent;
+using System.Threading;
+using Microsoft.Extensions.Hosting;
+using Umbraco.Core;
+using Umbraco.Core.Hosting;
+
+namespace Umbraco.Web.BackOffice.AspNetCore
+{
+ public class AspNetCoreHostingEnvironmentLifetime : IHostingEnvironmentLifetime
+ {
+ private readonly IHostApplicationLifetime _hostApplicationLifetime;
+ private readonly ConcurrentDictionary _registeredObjects =
+ new ConcurrentDictionary();
+
+ public AspNetCoreHostingEnvironmentLifetime(IHostApplicationLifetime hostApplicationLifetime)
+ {
+ _hostApplicationLifetime = hostApplicationLifetime;
+ }
+
+ public void RegisterObject(IRegisteredObject registeredObject)
+ {
+ var wrapped = new RegisteredObjectWrapper(registeredObject);
+ if (!_registeredObjects.TryAdd(registeredObject, wrapped))
+ {
+ throw new InvalidOperationException("Could not register object");
+ }
+
+ var cancellationTokenRegistration = _hostApplicationLifetime.ApplicationStopping.Register(() => wrapped.Stop(true));
+ wrapped.CancellationTokenRegistration = cancellationTokenRegistration;
+ }
+
+ public void UnregisterObject(IRegisteredObject registeredObject)
+ {
+ if (_registeredObjects.TryGetValue(registeredObject, out var wrapped))
+ {
+ wrapped.CancellationTokenRegistration.Unregister();
+ }
+ }
+
+
+ private class RegisteredObjectWrapper
+ {
+ private readonly IRegisteredObject _inner;
+
+ public RegisteredObjectWrapper(IRegisteredObject inner)
+ {
+ _inner = inner;
+ }
+
+ public CancellationTokenRegistration CancellationTokenRegistration { get; set; }
+
+ public void Stop(bool immediate)
+ {
+ _inner.Stop(immediate);
+ }
+ }
+ }
+}
diff --git a/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoBackOfficeApplicationBuilderExtensions.cs b/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoBackOfficeApplicationBuilderExtensions.cs
index a79838bd3e..feb122a48b 100644
--- a/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoBackOfficeApplicationBuilderExtensions.cs
+++ b/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoBackOfficeApplicationBuilderExtensions.cs
@@ -2,6 +2,9 @@ using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
+using Umbraco.Core;
+using Umbraco.Core.Composing;
+using Umbraco.Core.Hosting;
namespace Umbraco.Web.BackOffice.AspNetCore
{
@@ -14,5 +17,52 @@ namespace Umbraco.Web.BackOffice.AspNetCore
return app;
}
+ ///
+ /// Start Umbraco
+ ///
+ ///
+ ///
+ public static IApplicationBuilder UseUmbracoCore(this IApplicationBuilder app)
+ {
+ if (app == null) throw new ArgumentNullException(nameof(app));
+
+ // Register a listener for application shutdown in order to terminate the runtime
+ var hostLifetime = app.ApplicationServices.GetRequiredService();
+ var runtime = app.ApplicationServices.GetRequiredService();
+ var runtimeShutdown = new CoreRuntimeShutdown(runtime, hostLifetime);
+ hostLifetime.RegisterObject(runtimeShutdown);
+
+ // Start the runtime!
+ runtime.Start();
+
+ return app;
+ }
+
+ ///
+ /// Ensures the runtime is shutdown when the application is shutting down
+ ///
+ private class CoreRuntimeShutdown : IRegisteredObject
+ {
+ public CoreRuntimeShutdown(IRuntime runtime, IHostingEnvironmentLifetime hostLifetime)
+ {
+ _runtime = runtime;
+ _hostLifetime = hostLifetime;
+ }
+
+ private bool _completed = false;
+ private readonly IRuntime _runtime;
+ private readonly IHostingEnvironmentLifetime _hostLifetime;
+
+ public void Stop(bool immediate)
+ {
+ if (!_completed)
+ {
+ _completed = true;
+ _runtime.Terminate();
+ _hostLifetime.UnregisterObject(this);
+ }
+
+ }
+ }
}
}
diff --git a/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoCoreServiceCollectionExtensions.cs b/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoCoreServiceCollectionExtensions.cs
index 6c3cecad28..d283a7ffb1 100644
--- a/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoCoreServiceCollectionExtensions.cs
+++ b/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoCoreServiceCollectionExtensions.cs
@@ -19,8 +19,7 @@ using Umbraco.Core.Runtime;
namespace Umbraco.Web.BackOffice.AspNetCore
{
-
-
+ // TODO: Move to Umbraco.Web.Common
public static class UmbracoCoreServiceCollectionExtensions
{
///
@@ -73,11 +72,12 @@ namespace Umbraco.Web.BackOffice.AspNetCore
if (umbContainer is null) throw new ArgumentNullException(nameof(umbContainer));
if (entryAssembly is null) throw new ArgumentNullException(nameof(entryAssembly));
+ // Special case! The generic host adds a few default services but we need to manually add this one here NOW because
+ // we resolve it before the host finishes configuring in the call to CreateCompositionRoot
services.AddSingleton();
CreateCompositionRoot(services, out var logger, out var configs, out var ioHelper, out var hostingEnvironment, out var backOfficeInfo, out var profiler);
- // TODO: Get rid of this 'Current' requirement
var globalSettings = configs.Global();
var umbracoVersion = new UmbracoVersion(globalSettings);
@@ -95,9 +95,7 @@ namespace Umbraco.Web.BackOffice.AspNetCore
backOfficeInfo,
typeFinder);
- hostingEnvironment.RegisterObject(new CoreRuntimeShutdown(coreRuntime));
-
- var factory = coreRuntime.Boot(umbContainer);
+ var factory = coreRuntime.Configure(umbContainer);
return services;
}
@@ -119,7 +117,7 @@ namespace Umbraco.Web.BackOffice.AspNetCore
? (IMainDomLock)new SqlMainDomLock(logger, globalSettings, connStrings, dbProviderFactoryCreator)
: new MainDomSemaphoreLock(logger, hostingEnvironment);
- var mainDom = new MainDom(logger, hostingEnvironment, mainDomLock);
+ var mainDom = new MainDom(logger, mainDomLock);
var coreRuntime = new CoreRuntime(configs, umbracoVersion, ioHelper, logger, profiler, new AspNetCoreBootPermissionsChecker(),
hostingEnvironment, backOfficeInfo, dbProviderFactoryCreator, mainDom, typeFinder);
@@ -137,10 +135,6 @@ namespace Umbraco.Web.BackOffice.AspNetCore
var httpContextAccessor = serviceProvider.GetRequiredService();
var webHostEnvironment = serviceProvider.GetRequiredService();
- // TODO: I'm unsure about this, by doing this it means we are resolving a "Different" instance to the one
- // that controls the whole app because the instances comes from a different service provider. This
- // could cause some issues with shutdowns, etc... we need to investigate.
- var hostApplicationLifetime = serviceProvider.GetRequiredService();
configs = serviceProvider.GetService();
if (configs == null)
@@ -150,7 +144,7 @@ namespace Umbraco.Web.BackOffice.AspNetCore
var coreDebug = configs.CoreDebug();
var globalSettings = configs.Global();
- hostingEnvironment = new AspNetCoreHostingEnvironment(hostingSettings, webHostEnvironment, httpContextAccessor, hostApplicationLifetime);
+ hostingEnvironment = new AspNetCoreHostingEnvironment(hostingSettings, webHostEnvironment, httpContextAccessor);
ioHelper = new IOHelper(hostingEnvironment, globalSettings);
logger = SerilogLogger.CreateWithDefaultConfiguration(hostingEnvironment,
new AspNetCoreSessionIdResolver(httpContextAccessor),
@@ -170,28 +164,6 @@ namespace Umbraco.Web.BackOffice.AspNetCore
}
}
- ///
- /// Ensures the runtime is shutdown when the application is shutting down
- ///
- private class CoreRuntimeShutdown : IRegisteredObject
- {
- public CoreRuntimeShutdown(IRuntime runtime)
- {
- _runtime = runtime;
- }
-
- private bool _completed = false;
- private readonly IRuntime _runtime;
-
- public void Stop(bool immediate)
- {
- if (!_completed)
- {
- _completed = true;
- _runtime.Terminate();
- }
-
- }
- }
+
}
}
diff --git a/src/Umbraco.Web/AspNet/AspNetHostingEnvironment.cs b/src/Umbraco.Web/AspNet/AspNetHostingEnvironment.cs
index aa07894aa9..a61ad356d5 100644
--- a/src/Umbraco.Web/AspNet/AspNetHostingEnvironment.cs
+++ b/src/Umbraco.Web/AspNet/AspNetHostingEnvironment.cs
@@ -1,21 +1,15 @@
using System;
-using System.Collections;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
using System.Web;
using System.Web.Hosting;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Hosting;
-using Umbraco.Core.IO;
-using IRegisteredObject = Umbraco.Core.IRegisteredObject;
namespace Umbraco.Web.Hosting
{
public class AspNetHostingEnvironment : IHostingEnvironment
{
- private readonly ConcurrentDictionary _registeredObjects =
- new ConcurrentDictionary();
+
private readonly IHostingSettings _hostingSettings;
private string _localTempPath;
@@ -46,23 +40,7 @@ namespace Umbraco.Web.Hosting
}
public string ToAbsolute(string virtualPath, string root) => VirtualPathUtility.ToAbsolute(virtualPath, root);
- public void RegisterObject(IRegisteredObject registeredObject)
- {
- var wrapped = new RegisteredObjectWrapper(registeredObject);
- if (!_registeredObjects.TryAdd(registeredObject, wrapped))
- {
- throw new InvalidOperationException("Could not register object");
- }
- HostingEnvironment.RegisterObject(wrapped);
- }
-
- public void UnregisterObject(IRegisteredObject registeredObject)
- {
- if (_registeredObjects.TryGetValue(registeredObject, out var wrapped))
- {
- HostingEnvironment.UnregisterObject(wrapped);
- }
- }
+
public string LocalTempPath
{
@@ -101,20 +79,7 @@ namespace Umbraco.Web.Hosting
}
}
}
- private class RegisteredObjectWrapper : System.Web.Hosting.IRegisteredObject
- {
- private readonly IRegisteredObject _inner;
-
- public RegisteredObjectWrapper(IRegisteredObject inner)
- {
- _inner = inner;
- }
-
- public void Stop(bool immediate)
- {
- _inner.Stop(immediate);
- }
- }
+
}
diff --git a/src/Umbraco.Web/AspNet/AspNetHostingLifetime.cs b/src/Umbraco.Web/AspNet/AspNetHostingLifetime.cs
new file mode 100644
index 0000000000..316ecb8389
--- /dev/null
+++ b/src/Umbraco.Web/AspNet/AspNetHostingLifetime.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Concurrent;
+using System.Web.Hosting;
+using Umbraco.Core.Hosting;
+using IRegisteredObject = Umbraco.Core.IRegisteredObject;
+
+namespace Umbraco.Web.Hosting
+{
+ public class AspNetHostingLifetime : IHostingEnvironmentLifetime
+ {
+ private readonly ConcurrentDictionary _registeredObjects =
+ new ConcurrentDictionary();
+
+ public void RegisterObject(IRegisteredObject registeredObject)
+ {
+ var wrapped = new RegisteredObjectWrapper(registeredObject);
+ if (!_registeredObjects.TryAdd(registeredObject, wrapped))
+ {
+ throw new InvalidOperationException("Could not register object");
+ }
+ HostingEnvironment.RegisterObject(wrapped);
+ }
+
+ public void UnregisterObject(IRegisteredObject registeredObject)
+ {
+ if (_registeredObjects.TryGetValue(registeredObject, out var wrapped))
+ {
+ HostingEnvironment.UnregisterObject(wrapped);
+ }
+ }
+
+ private class RegisteredObjectWrapper : System.Web.Hosting.IRegisteredObject
+ {
+ private readonly IRegisteredObject _inner;
+
+ public RegisteredObjectWrapper(IRegisteredObject inner)
+ {
+ _inner = inner;
+ }
+
+ public void Stop(bool immediate)
+ {
+ _inner.Stop(immediate);
+ }
+ }
+ }
+}
diff --git a/src/Umbraco.Web/Profiling/WebProfilingController.cs b/src/Umbraco.Web/Profiling/WebProfilingController.cs
index b37a7eefb8..d8f71b5c85 100644
--- a/src/Umbraco.Web/Profiling/WebProfilingController.cs
+++ b/src/Umbraco.Web/Profiling/WebProfilingController.cs
@@ -1,6 +1,7 @@
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
+using Umbraco.Core.Hosting;
using Umbraco.Core.Logging;
using Umbraco.Core.Mapping;
using Umbraco.Core.Persistence;
@@ -18,7 +19,7 @@ namespace Umbraco.Web.Profiling
[UmbracoApplicationAuthorize(Core.Constants.Applications.Settings)]
public class WebProfilingController : UmbracoAuthorizedJsonController
{
- private readonly IRuntimeState _runtimeState;
+ private readonly IHostingEnvironment _hosting;
public WebProfilingController(
IGlobalSettings globalSettings,
@@ -30,17 +31,18 @@ namespace Umbraco.Web.Profiling
IRuntimeState runtimeState,
IShortStringHelper shortStringHelper,
UmbracoMapper umbracoMapper,
- IPublishedUrlProvider publishedUrlProvider)
+ IPublishedUrlProvider publishedUrlProvider,
+ IHostingEnvironment hosting)
: base(globalSettings, umbracoContextAccessor, sqlContext, services, appCaches, logger, runtimeState, shortStringHelper, umbracoMapper, publishedUrlProvider)
{
- _runtimeState = runtimeState;
+ _hosting = hosting;
}
public object GetStatus()
{
return new
{
- Enabled = _runtimeState.Debug
+ Enabled = _hosting.IsDebugMode
};
}
}}
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index 5eb60cb629..ce08d5498d 100755
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -134,6 +134,7 @@
+
diff --git a/src/Umbraco.Web/UmbracoApplication.cs b/src/Umbraco.Web/UmbracoApplication.cs
index 9f24da95e3..30d3fe5041 100644
--- a/src/Umbraco.Web/UmbracoApplication.cs
+++ b/src/Umbraco.Web/UmbracoApplication.cs
@@ -32,7 +32,7 @@ namespace Umbraco.Web
? (IMainDomLock)new SqlMainDomLock(logger, globalSettings, connectionStrings, dbProviderFactoryCreator)
: new MainDomSemaphoreLock(logger, hostingEnvironment);
- var mainDom = new MainDom(logger, hostingEnvironment, mainDomLock);
+ var mainDom = new MainDom(logger, mainDomLock);
var requestCache = new HttpRequestAppCache(() => HttpContext.Current?.Items);
var umbracoBootPermissionChecker = new AspNetUmbracoBootPermissionChecker();
diff --git a/src/Umbraco.Web/UmbracoApplicationBase.cs b/src/Umbraco.Web/UmbracoApplicationBase.cs
index ce5f1304cd..0963ad3c07 100644
--- a/src/Umbraco.Web/UmbracoApplicationBase.cs
+++ b/src/Umbraco.Web/UmbracoApplicationBase.cs
@@ -152,7 +152,9 @@ namespace Umbraco.Web
Umbraco.Composing.Current.Profiler,
Umbraco.Composing.Current.HostingEnvironment,
Umbraco.Composing.Current.BackOfficeInfo);
- _factory = Current.Factory = _runtime.Boot(register);
+ _factory = Current.Factory = _runtime.Configure(register);
+
+ _runtime.Start();
}
// called by ASP.NET (auto event wireup) once per app domain
diff --git a/src/Umbraco.Web/UmbracoContext.cs b/src/Umbraco.Web/UmbracoContext.cs
index 6f5fc26f90..9cc651f359 100644
--- a/src/Umbraco.Web/UmbracoContext.cs
+++ b/src/Umbraco.Web/UmbracoContext.cs
@@ -150,7 +150,7 @@ namespace Umbraco.Web
{
var request = GetRequestFromContext();
//NOTE: the request can be null during app startup!
- return Current.RuntimeState.Debug
+ return Current.HostingEnvironment.IsDebugMode
&& request != null
&& (string.IsNullOrEmpty(request["umbdebugshowtrace"]) == false
|| string.IsNullOrEmpty(request["umbdebug"]) == false
diff --git a/src/Umbraco.Web/UrlHelperExtensions.cs b/src/Umbraco.Web/UrlHelperExtensions.cs
index a0bf5d3ded..f0ee309630 100644
--- a/src/Umbraco.Web/UrlHelperExtensions.cs
+++ b/src/Umbraco.Web/UrlHelperExtensions.cs
@@ -143,12 +143,12 @@ namespace Umbraco.Web
//in case the user bypasses the installer and just bumps the web.config or client dependency config
//if in debug mode, always burst the cache
- if (Current.RuntimeState.Debug)
+ if (Current.HostingEnvironment.IsDebugMode)
{
return DateTime.Now.Ticks.ToString(CultureInfo.InvariantCulture).GenerateHash();
}
- var version = Current.RuntimeState.SemanticVersion.ToSemanticString();
+ var version = Current.UmbracoVersion.SemanticVersion.ToSemanticString();
return $"{version}.{ClientDependencySettings.Instance.Version}".GenerateHash();
}
}