Merge remote-tracking branch 'origin/netcore/dev' into netcore/feature/ab5820-webprofiler-aspnetcore
# Conflicts: # src/Umbraco.Web.BackOffice/AspNetCore/UmbracoCoreServiceCollectionExtensions.cs # src/Umbraco.Web.Common/AspNetCore/AspNetCoreUmbracoApplicationLifetime.cs # src/Umbraco.Web.UI.NetCore/Startup.cs
This commit is contained in:
@@ -166,3 +166,4 @@ build/temp/
|
||||
/src/ApiDocs/api/*
|
||||
/src/Umbraco.Web.UI.NetCore/wwwroot/Media/*
|
||||
/src/Umbraco.Web.UI.NetCore/wwwroot/is-cache/*
|
||||
/src/Umbraco.Tests.Integration/App_Data/*
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Data.Common;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Configuration.Models
|
||||
{
|
||||
internal class ConnectionStrings : IConnectionStrings
|
||||
public class ConnectionStrings : IConnectionStrings
|
||||
{
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
@@ -17,8 +17,43 @@ namespace Umbraco.Configuration.Models
|
||||
|
||||
public ConfigConnectionString this[string key]
|
||||
{
|
||||
get => new ConfigConnectionString(_configuration.GetConnectionString(key), "System.Data.SqlClient", key);
|
||||
get
|
||||
{
|
||||
var connectionString = _configuration.GetConnectionString(key);
|
||||
var provider = ParseProvider(connectionString);
|
||||
return new ConfigConnectionString(connectionString, provider, key);
|
||||
}
|
||||
set => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private string ParseProvider(string connectionString)
|
||||
{
|
||||
if (string.IsNullOrEmpty(connectionString))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var builder = new DbConnectionStringBuilder();
|
||||
|
||||
builder.ConnectionString = connectionString;
|
||||
|
||||
if (builder.TryGetValue("Data Source", out var ds) && ds is string dataSource)
|
||||
{
|
||||
if (dataSource.EndsWith(".sdf"))
|
||||
{
|
||||
return Constants.DbProviderNames.SqlCe;
|
||||
}
|
||||
}
|
||||
|
||||
if (builder.TryGetValue("Server", out var s) && s is string server && builder.TryGetValue("Database", out var db) && db is string database)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(server) && !string.IsNullOrEmpty(database))
|
||||
{
|
||||
return Constants.DbProviderNames.SqlServer;
|
||||
}
|
||||
}
|
||||
|
||||
throw new ArgumentException("Cannot determine provider name from connection string", nameof(connectionString));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,13 +33,13 @@ namespace Umbraco.Core.Composing
|
||||
/// <param name="ioHelper">An IOHelper</param>
|
||||
public Composition(IRegister register, TypeLoader typeLoader, IProfilingLogger logger, IRuntimeState runtimeState, Configs configs, IIOHelper ioHelper, AppCaches appCaches)
|
||||
{
|
||||
_register = register;
|
||||
TypeLoader = typeLoader;
|
||||
Logger = logger;
|
||||
RuntimeState = runtimeState;
|
||||
Configs = configs;
|
||||
IOHelper = ioHelper;
|
||||
AppCaches = appCaches;
|
||||
_register = register ?? throw new ArgumentNullException(nameof(register));
|
||||
TypeLoader = typeLoader ?? throw new ArgumentNullException(nameof(typeLoader));
|
||||
Logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
RuntimeState = runtimeState ?? throw new ArgumentNullException(nameof(runtimeState));
|
||||
Configs = configs ?? throw new ArgumentNullException(nameof(configs));
|
||||
IOHelper = ioHelper ?? throw new ArgumentNullException(nameof(ioHelper));
|
||||
AppCaches = appCaches ?? throw new ArgumentNullException(nameof(appCaches));
|
||||
}
|
||||
|
||||
#region Services
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace Umbraco.Core.Composing
|
||||
{
|
||||
"Umbraco.Core",
|
||||
"Umbraco.Web",
|
||||
"Umbraco.Web.BackOffice",
|
||||
"Umbraco.Infrastructure",
|
||||
"Umbraco.PublishedCache.NuCache",
|
||||
"Umbraco.ModelsBuilder.Embedded",
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Umbraco.Core.Hosting
|
||||
{
|
||||
public interface IApplicationShutdownRegistry
|
||||
{
|
||||
void RegisterObject(IRegisteredObject registeredObject);
|
||||
void UnregisterObject(IRegisteredObject registeredObject);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
|
||||
namespace Umbraco.Net
|
||||
{
|
||||
// TODO: This shouldn't be in this namespace?
|
||||
public interface IUmbracoApplicationLifetime
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -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.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 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
|
||||
/// </remarks>
|
||||
bool IsMainDom { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Tries to acquire the MainDom, returns true if successful else false
|
||||
/// </summary>
|
||||
/// <param name="hostingEnvironment"></param>
|
||||
/// <returns></returns>
|
||||
bool Acquire(IApplicationShutdownRegistry hostingEnvironment);
|
||||
|
||||
/// <summary>
|
||||
/// Registers a resource that requires the current AppDomain to be the main domain to function.
|
||||
/// </summary>
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Umbraco.Core.Runtime
|
||||
#region Vars
|
||||
|
||||
private readonly ILogger _logger;
|
||||
private readonly IHostingEnvironment _hostingEnvironment;
|
||||
private IApplicationShutdownRegistry _hostingEnvironment;
|
||||
private readonly IMainDomLock _mainDomLock;
|
||||
|
||||
// our own lock for local consistency
|
||||
@@ -42,17 +42,25 @@ 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(IApplicationShutdownRegistry hostingEnvironment)
|
||||
{
|
||||
_hostingEnvironment = hostingEnvironment ?? throw new ArgumentNullException(nameof(hostingEnvironment));
|
||||
|
||||
return LazyInitializer.EnsureInitialized(ref _isMainDom, ref _isInitialized, ref _locko, () =>
|
||||
{
|
||||
hostingEnvironment.RegisterObject(this);
|
||||
return Acquire();
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a resource that requires the current AppDomain to be the main domain to function.
|
||||
/// </summary>
|
||||
@@ -180,10 +188,9 @@ namespace Umbraco.Core.Runtime
|
||||
/// Gets a value indicating whether the current domain is the main domain.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 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
|
||||
/// </remarks>
|
||||
public bool IsMainDom => LazyInitializer.EnsureInitialized(ref _isMainDom, ref _isInitialized, ref _locko, () => Acquire());
|
||||
public bool IsMainDom => _isMainDom;
|
||||
|
||||
// IRegisteredObject
|
||||
void IRegisteredObject.Stop(bool immediate)
|
||||
@@ -193,7 +200,7 @@ namespace Umbraco.Core.Runtime
|
||||
// The web app is stopping, need to wind down
|
||||
Dispose(true);
|
||||
|
||||
_hostingEnvironment.UnregisterObject(this);
|
||||
_hostingEnvironment?.UnregisterObject(this);
|
||||
}
|
||||
|
||||
#region IDisposable Support
|
||||
|
||||
@@ -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<RecurringTaskBase> 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<bool> PerformRunAsync(CancellationToken token)
|
||||
{
|
||||
// not on replicas nor unknown role servers
|
||||
switch (_runtime.ServerRole)
|
||||
switch (_serverRegistrar.GetCurrentServerRole())
|
||||
{
|
||||
case ServerRole.Replica:
|
||||
_logger.Debug<KeepAlive>("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<KeepAlive>("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<KeepAlive>("No umbracoApplicationUrl for service (yet), skip.");
|
||||
|
||||
@@ -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<RecurringTaskBase> runner, int delayMilliseconds, int periodMilliseconds,
|
||||
IEnumerable<DirectoryInfo> 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<TempFileCleanup>("Does not run if not MainDom.");
|
||||
return false; // do NOT repeat, going down
|
||||
|
||||
@@ -13,13 +13,15 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
/// <param name="register">The application register.</param>
|
||||
/// <returns>The application factory.</returns>
|
||||
IFactory Boot(IRegister register);
|
||||
IFactory Configure(IRegister register);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the runtime state.
|
||||
/// </summary>
|
||||
IRuntimeState State { get; }
|
||||
|
||||
void Start();
|
||||
|
||||
/// <summary>
|
||||
/// Terminates the runtime.
|
||||
/// </summary>
|
||||
|
||||
@@ -25,33 +25,12 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
SemVersion SemanticVersion { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the application is running in debug mode.
|
||||
/// </summary>
|
||||
bool Debug { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the runtime is the current main domain.
|
||||
/// </summary>
|
||||
bool IsMainDom { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the server's current role.
|
||||
/// </summary>
|
||||
ServerRole ServerRole { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Umbraco application url.
|
||||
/// </summary>
|
||||
/// <remarks>This is eg "http://www.example.com".</remarks>
|
||||
Uri ApplicationUrl { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Umbraco application virtual path.
|
||||
/// </summary>
|
||||
/// <remarks>This is either "/" or eg "/virtual".</remarks>
|
||||
string ApplicationVirtualPath { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the runtime level of execution.
|
||||
/// </summary>
|
||||
@@ -77,6 +56,5 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
BootFailedException BootFailedException { get; }
|
||||
|
||||
IMainDom MainDom { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
/// <inheritdoc />
|
||||
public bool IsMainDom { get; private set; } = true;
|
||||
|
||||
// always acquire
|
||||
public bool Acquire(IApplicationShutdownRegistry hostingEnvironment) => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Register(Action release, int weight = 100)
|
||||
=> Register(null, release, weight);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -91,7 +91,6 @@ namespace Umbraco.Web.Compose
|
||||
private readonly BackgroundTaskRunner<IBackgroundTask> _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,
|
||||
IApplicationShutdownRegistry hostingEnvironment,
|
||||
IRequestAccessor requestAccessor)
|
||||
{
|
||||
_runtime = runtime;
|
||||
_logger = logger;
|
||||
_registrationService = registrationService;
|
||||
_indexRebuilder = indexRebuilder;
|
||||
_requestAccessor = requestAccessor;
|
||||
|
||||
// create task runner for DatabaseServerRegistrar
|
||||
|
||||
@@ -10,7 +10,7 @@ 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;
|
||||
|
||||
@@ -13,8 +13,9 @@ namespace Umbraco.Core.Composing
|
||||
/// <param name="builder"></param>
|
||||
/// <returns></returns>
|
||||
public static IHostBuilder UseUmbraco(this IHostBuilder builder)
|
||||
{
|
||||
return builder.UseServiceProviderFactory(new UmbracoServiceProviderFactory());
|
||||
}
|
||||
=> builder.UseUmbraco(new UmbracoServiceProviderFactory());
|
||||
|
||||
public static IHostBuilder UseUmbraco(this IHostBuilder builder, UmbracoServiceProviderFactory umbracoServiceProviderFactory)
|
||||
=> builder.UseServiceProviderFactory(umbracoServiceProviderFactory);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Hosting;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence;
|
||||
@@ -15,6 +16,9 @@ namespace Umbraco.Core
|
||||
/// <summary>
|
||||
/// Registers essential services.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// These services are all either created by the runtime or used to construct the runtime
|
||||
/// </remarks>
|
||||
public static void RegisterEssentials(this Composition composition,
|
||||
ILogger logger, IProfiler profiler, IProfilingLogger profilingLogger,
|
||||
IMainDom mainDom,
|
||||
@@ -25,8 +29,10 @@ namespace Umbraco.Core
|
||||
ITypeFinder typeFinder,
|
||||
IIOHelper ioHelper,
|
||||
IUmbracoVersion umbracoVersion,
|
||||
IDbProviderFactoryCreator dbProviderFactoryCreator)
|
||||
{
|
||||
IDbProviderFactoryCreator dbProviderFactoryCreator,
|
||||
IHostingEnvironment hostingEnvironment,
|
||||
IBackOfficeInfo backOfficeInfo)
|
||||
{
|
||||
composition.RegisterUnique(logger);
|
||||
composition.RegisterUnique(profiler);
|
||||
composition.RegisterUnique(profilingLogger);
|
||||
@@ -42,6 +48,8 @@ namespace Umbraco.Core
|
||||
composition.RegisterUnique(umbracoVersion);
|
||||
composition.RegisterUnique(dbProviderFactoryCreator);
|
||||
composition.RegisterUnique(factory => factory.GetInstance<IUmbracoDatabaseFactory>().BulkSqlInsertProvider);
|
||||
composition.RegisterUnique(hostingEnvironment);
|
||||
composition.RegisterUnique(backOfficeInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,10 +9,10 @@ using Umbraco.Core.Cookie;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Migrations.Install;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Net;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Serialization;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Net;
|
||||
using Umbraco.Web.Install.Models;
|
||||
|
||||
namespace Umbraco.Web.Install
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Net;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Install.Models;
|
||||
|
||||
namespace Umbraco.Web.Install.InstallSteps
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace Umbraco.Core.Migrations.Install
|
||||
IIOHelper ioHelper,
|
||||
IUmbracoVersion umbracoVersion,
|
||||
IDbProviderFactoryCreator dbProviderFactoryCreator,
|
||||
IConfigManipulator configManipulator)
|
||||
IConfigManipulator configManipulator)
|
||||
{
|
||||
_scopeProvider = scopeProvider;
|
||||
_globalSettings = globalSettings;
|
||||
|
||||
@@ -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<IServerMessenger>(factory
|
||||
=> new DatabaseServerMessenger(
|
||||
factory.GetInstance<IRuntimeState>(),
|
||||
factory.GetInstance<IMainDom>(),
|
||||
factory.GetInstance<IScopeProvider>(),
|
||||
factory.GetInstance<ISqlContext>(),
|
||||
factory.GetInstance<IProfilingLogger>(),
|
||||
factory.GetInstance<IServerRegistrar>(),
|
||||
true, new DatabaseServerMessengerOptions(),
|
||||
factory.GetInstance<IHostingEnvironment>(),
|
||||
factory.GetInstance<CacheRefresherCollection>()
|
||||
@@ -176,6 +177,8 @@ namespace Umbraco.Core.Runtime
|
||||
// Grid config is not a real config file as we know them
|
||||
composition.RegisterUnique<IGridConfig, GridConfig>();
|
||||
|
||||
// Config manipulator
|
||||
composition.RegisterUnique<IConfigManipulator, JsonConfigManipulator>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,11 @@ 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;
|
||||
|
||||
|
||||
public CoreRuntime(
|
||||
Configs configs,
|
||||
IUmbracoVersion umbracoVersion,
|
||||
@@ -65,11 +62,7 @@ namespace Umbraco.Core.Runtime
|
||||
// runtime state
|
||||
// beware! must use '() => _factory.GetInstance<T>()' and NOT '_factory.GetInstance<T>'
|
||||
// as the second one captures the current value (null) and therefore fails
|
||||
_state = new RuntimeState(Logger,
|
||||
Configs.Global(),
|
||||
new Lazy<IMainDom>(() => mainDom),
|
||||
new Lazy<IServerRegistrar>(() => _factory.GetInstance<IServerRegistrar>()),
|
||||
UmbracoVersion,HostingEnvironment, BackOfficeInfo)
|
||||
_state = new RuntimeState(Logger, Configs.Global(), UmbracoVersion, BackOfficeInfo)
|
||||
{
|
||||
Level = RuntimeLevel.Boot
|
||||
};
|
||||
@@ -81,13 +74,13 @@ namespace Umbraco.Core.Runtime
|
||||
protected ILogger Logger { get; }
|
||||
|
||||
protected IBackOfficeInfo BackOfficeInfo { get; }
|
||||
|
||||
public IDbProviderFactoryCreator DbProviderFactoryCreator { get; }
|
||||
//public IBulkSqlInsertProvider BulkSqlInsertProvider { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the profiler.
|
||||
/// </summary>
|
||||
protected IProfiler Profiler { get; set; }
|
||||
protected IProfiler Profiler { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the profiling logger.
|
||||
@@ -110,11 +103,13 @@ namespace Umbraco.Core.Runtime
|
||||
/// <inheritdoc />
|
||||
public IRuntimeState State => _state;
|
||||
|
||||
public IMainDom MainDom { get; private set; }
|
||||
public IMainDom MainDom { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual IFactory Boot(IRegister register)
|
||||
public virtual IFactory Configure(IRegister register)
|
||||
{
|
||||
if (register is null) throw new ArgumentNullException(nameof(register));
|
||||
|
||||
// create and register the essential services
|
||||
// ie the bare minimum required to boot
|
||||
|
||||
@@ -139,25 +134,24 @@ namespace Umbraco.Core.Runtime
|
||||
|
||||
// application environment
|
||||
ConfigureUnhandledException();
|
||||
ConfigureApplicationRootPath();
|
||||
|
||||
Boot(register, timer);
|
||||
return _factory = Configure(register, timer);
|
||||
}
|
||||
|
||||
return _factory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Boots the runtime within a timer.
|
||||
/// Configure the runtime within a timer.
|
||||
/// </summary>
|
||||
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);
|
||||
@@ -171,31 +165,12 @@ namespace Umbraco.Core.Runtime
|
||||
// type finder/loader
|
||||
var typeLoader = new TypeLoader(IOHelper, TypeFinder, appCaches.RuntimeCache, new DirectoryInfo(HostingEnvironment.LocalTempPath), ProfilingLogger);
|
||||
|
||||
// runtime state
|
||||
// beware! must use '() => _factory.GetInstance<T>()' and NOT '_factory.GetInstance<T>'
|
||||
// as the second one captures the current value (null) and therefore fails
|
||||
_state = new RuntimeState(Logger,
|
||||
Configs.Global(),
|
||||
new Lazy<IMainDom>(() => _factory.GetInstance<IMainDom>()),
|
||||
new Lazy<IServerRegistrar>(() => _factory.GetInstance<IServerRegistrar>()),
|
||||
UmbracoVersion, HostingEnvironment, BackOfficeInfo)
|
||||
{
|
||||
Level = RuntimeLevel.Boot
|
||||
};
|
||||
|
||||
// create the composition
|
||||
composition = new Composition(register, typeLoader, ProfilingLogger, _state, Configs, IOHelper, appCaches);
|
||||
composition.RegisterEssentials(Logger, Profiler, ProfilingLogger, MainDom, appCaches, databaseFactory, typeLoader, _state, TypeFinder, IOHelper, UmbracoVersion, DbProviderFactoryCreator);
|
||||
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<IRuntime>(_ => this, Lifetime.Singleton);
|
||||
|
||||
// determine our runtime level
|
||||
DetermineRuntimeLevel(databaseFactory, ProfilingLogger);
|
||||
@@ -213,13 +188,7 @@ namespace Umbraco.Core.Runtime
|
||||
composers.Compose();
|
||||
|
||||
// create the factory
|
||||
_factory = composition.CreateFactory();
|
||||
|
||||
// create & initialize the components
|
||||
_components = _factory.GetInstance<ComponentCollection>();
|
||||
_components.Initialize();
|
||||
|
||||
|
||||
factory = composition.CreateFactory();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -236,11 +205,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 */ }
|
||||
}
|
||||
@@ -254,7 +223,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<IApplicationShutdownRegistry>();
|
||||
if (hostingEnvironmentLifetime == null)
|
||||
throw new InvalidOperationException($"An instance of {typeof(IApplicationShutdownRegistry)} 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<IApplicationShutdownRegistry>());
|
||||
|
||||
// create & initialize the components
|
||||
_components = _factory.GetInstance<ComponentCollection>();
|
||||
_components.Initialize();
|
||||
}
|
||||
|
||||
protected virtual void ConfigureUnhandledException()
|
||||
@@ -281,13 +272,13 @@ namespace Umbraco.Core.Runtime
|
||||
IOHelper.SetRootDirectory(path);
|
||||
}
|
||||
|
||||
private bool AcquireMainDom(IMainDom mainDom)
|
||||
private bool AcquireMainDom(IMainDom mainDom, IApplicationShutdownRegistry applicationShutdownRegistry)
|
||||
{
|
||||
using (var timer = ProfilingLogger.DebugDuration<CoreRuntime>("Acquiring MainDom.", "Acquired."))
|
||||
{
|
||||
try
|
||||
{
|
||||
return mainDom.IsMainDom;
|
||||
return mainDom.Acquire(applicationShutdownRegistry);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -346,12 +337,6 @@ namespace Umbraco.Core.Runtime
|
||||
_components?.Terminate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Composes the runtime.
|
||||
/// </summary>
|
||||
public virtual void Compose(Composition composition)
|
||||
{
|
||||
}
|
||||
|
||||
#region Getters
|
||||
|
||||
@@ -392,5 +377,6 @@ namespace Umbraco.Core.Runtime
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace Umbraco.Web.Runtime
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
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<CoreRuntime>("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
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Umbraco.Core
|
||||
public static class RuntimeOptions
|
||||
{
|
||||
private static List<Action<IProfilingLogger>> _onBoot;
|
||||
private static List<Action<Composition, AppCaches, TypeLoader, IUmbracoDatabaseFactory>> _onEssentials;
|
||||
private static List<Action<IFactory>> _onEssentials;
|
||||
|
||||
/// <summary>
|
||||
/// Executes the RuntimeBoot handlers.
|
||||
@@ -33,13 +33,13 @@ namespace Umbraco.Core
|
||||
/// <summary>
|
||||
/// Executes the RuntimeEssentials handlers.
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -64,10 +64,10 @@ namespace Umbraco.Core
|
||||
/// essential things (AppCaches, a TypeLoader, and a database factory) but
|
||||
/// before anything else.</para>
|
||||
/// </remarks>
|
||||
public static void OnRuntimeEssentials(Action<Composition, AppCaches, TypeLoader, IUmbracoDatabaseFactory> action)
|
||||
public static void OnRuntimeEssentials(Action<IFactory> action)
|
||||
{
|
||||
if (_onEssentials == null)
|
||||
_onEssentials = new List<Action<Composition, AppCaches, TypeLoader, IUmbracoDatabaseFactory>>();
|
||||
_onEssentials = new List<Action<IFactory>>();
|
||||
_onEssentials.Add(action);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,46 +22,22 @@ namespace Umbraco.Core
|
||||
private readonly ILogger _logger;
|
||||
private readonly IGlobalSettings _globalSettings;
|
||||
private readonly ConcurrentHashSet<string> _applicationUrls = new ConcurrentHashSet<string>();
|
||||
private readonly Lazy<IMainDom> _mainDom;
|
||||
private readonly Lazy<IServerRegistrar> _serverRegistrar;
|
||||
private readonly IUmbracoVersion _umbracoVersion;
|
||||
private readonly IHostingEnvironment _hostingEnvironment;
|
||||
private readonly IBackOfficeInfo _backOfficeInfo;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RuntimeState"/> class.
|
||||
/// </summary>
|
||||
public RuntimeState(ILogger logger, IGlobalSettings globalSettings,
|
||||
Lazy<IMainDom> mainDom, Lazy<IServerRegistrar> serverRegistrar, IUmbracoVersion umbracoVersion,
|
||||
IHostingEnvironment hostingEnvironment,
|
||||
IUmbracoVersion umbracoVersion,
|
||||
IBackOfficeInfo backOfficeInfo)
|
||||
{
|
||||
_logger = logger;
|
||||
_globalSettings = globalSettings;
|
||||
_mainDom = mainDom;
|
||||
_serverRegistrar = serverRegistrar;
|
||||
_umbracoVersion = umbracoVersion;
|
||||
_hostingEnvironment = hostingEnvironment;
|
||||
_backOfficeInfo = backOfficeInfo;
|
||||
|
||||
ApplicationVirtualPath = _hostingEnvironment.ApplicationVirtualPath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the server registrar.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>This is NOT exposed in the interface.</para>
|
||||
/// </remarks>
|
||||
private IServerRegistrar ServerRegistrar => _serverRegistrar.Value;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the application MainDom.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>This is NOT exposed in the interface as MainDom is internal.</para>
|
||||
/// </remarks>
|
||||
public IMainDom MainDom => _mainDom.Value;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Version Version => _umbracoVersion.Current;
|
||||
@@ -72,26 +48,14 @@ namespace Umbraco.Core
|
||||
/// <inheritdoc />
|
||||
public SemVersion SemanticVersion => _umbracoVersion.SemanticVersion;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Debug => _hostingEnvironment.IsDebugMode;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsMainDom => MainDom.IsMainDom;
|
||||
|
||||
/// <inheritdoc />
|
||||
public ServerRole ServerRole => ServerRegistrar.GetCurrentServerRole();
|
||||
|
||||
/// <inheritdoc />
|
||||
public Uri ApplicationUrl { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string ApplicationVirtualPath { get; }
|
||||
public string CurrentMigrationState { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string CurrentMigrationState { get; internal set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string FinalMigrationState { get; internal set; }
|
||||
public string FinalMigrationState { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public RuntimeLevel Level { get; internal set; } = RuntimeLevel.Unknown;
|
||||
@@ -253,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;
|
||||
|
||||
@@ -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 IApplicationShutdownRegistry _hostingEnvironment;
|
||||
private readonly object _locker = new object();
|
||||
|
||||
private readonly BufferBlock<T> _tasks = new BufferBlock<T>(new DataflowBlockOptions());
|
||||
@@ -105,7 +105,7 @@ namespace Umbraco.Web.Scheduling
|
||||
/// <param name="logger">A logger.</param>
|
||||
/// <param name="hostingEnvironment">The hosting environment</param>
|
||||
/// <param name="hook">An optional main domain hook.</param>
|
||||
public BackgroundTaskRunner(ILogger logger, IHostingEnvironment hostingEnvironment, MainDomHook hook = null)
|
||||
public BackgroundTaskRunner(ILogger logger, IApplicationShutdownRegistry hostingEnvironment, MainDomHook hook = null)
|
||||
: this(typeof(T).FullName, new BackgroundTaskRunnerOptions(), logger, hostingEnvironment, hook)
|
||||
{ }
|
||||
|
||||
@@ -116,7 +116,7 @@ namespace Umbraco.Web.Scheduling
|
||||
/// <param name="logger">A logger.</param>
|
||||
/// <param name="hostingEnvironment">The hosting environment</param>
|
||||
/// <param name="hook">An optional main domain hook.</param>
|
||||
public BackgroundTaskRunner(string name, ILogger logger, IHostingEnvironment hostingEnvironment, MainDomHook hook = null)
|
||||
public BackgroundTaskRunner(string name, ILogger logger, IApplicationShutdownRegistry hostingEnvironment, MainDomHook hook = null)
|
||||
: this(name, new BackgroundTaskRunnerOptions(), logger, hostingEnvironment, hook)
|
||||
{ }
|
||||
|
||||
@@ -127,7 +127,7 @@ namespace Umbraco.Web.Scheduling
|
||||
/// <param name="logger">A logger.</param>
|
||||
/// <param name="hostingEnvironment">The hosting environment</param>
|
||||
/// <param name="hook">An optional main domain hook.</param>
|
||||
public BackgroundTaskRunner(BackgroundTaskRunnerOptions options, ILogger logger, IHostingEnvironment hostingEnvironment, MainDomHook hook = null)
|
||||
public BackgroundTaskRunner(BackgroundTaskRunnerOptions options, ILogger logger, IApplicationShutdownRegistry hostingEnvironment, MainDomHook hook = null)
|
||||
: this(typeof(T).FullName, options, logger, hostingEnvironment, hook)
|
||||
{ }
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace Umbraco.Web.Scheduling
|
||||
/// <param name="logger">A logger.</param>
|
||||
/// <param name="hostingEnvironment">The hosting environment</param>
|
||||
/// <param name="hook">An optional main domain hook.</param>
|
||||
public BackgroundTaskRunner(string name, BackgroundTaskRunnerOptions options, ILogger logger, IHostingEnvironment hostingEnvironment, MainDomHook hook = null)
|
||||
public BackgroundTaskRunner(string name, BackgroundTaskRunnerOptions options, ILogger logger, IApplicationShutdownRegistry hostingEnvironment, MainDomHook hook = null)
|
||||
{
|
||||
_options = options ?? throw new ArgumentNullException(nameof(options));
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
@@ -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<RecurringTaskBase> 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<bool> 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<HealthCheckNotifier>("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<HealthCheckNotifier>("Does not run if not MainDom.");
|
||||
return false; // do NOT repeat, going down
|
||||
|
||||
@@ -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<RecurringTaskBase> 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<LogScrubber>("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<LogScrubber>("Does not run if not MainDom.");
|
||||
return false; // do NOT repeat, going down
|
||||
|
||||
@@ -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<RecurringTaskBase> 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<ScheduledPublishing>("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<ScheduledPublishing>("Does not run if not MainDom.");
|
||||
return false; // do NOT repeat, going down
|
||||
|
||||
@@ -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 IApplicationShutdownRegistry _hostingEnvironment;
|
||||
private readonly IScopeProvider _scopeProvider;
|
||||
private readonly HealthCheckCollection _healthChecks;
|
||||
private readonly HealthCheckNotificationMethodCollection _notifications;
|
||||
@@ -43,7 +45,6 @@ namespace Umbraco.Web.Scheduling
|
||||
|
||||
private BackgroundTaskRunner<IBackgroundTask> _keepAliveRunner;
|
||||
private BackgroundTaskRunner<IBackgroundTask> _publishingRunner;
|
||||
private BackgroundTaskRunner<IBackgroundTask> _tasksRunner;
|
||||
private BackgroundTaskRunner<IBackgroundTask> _scrubberRunner;
|
||||
private BackgroundTaskRunner<IBackgroundTask> _fileCleanupRunner;
|
||||
private BackgroundTaskRunner<IBackgroundTask> _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,
|
||||
IApplicationShutdownRegistry 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<IBackgroundTask>("KeepAlive", _logger, _hostingEnvironment);
|
||||
_publishingRunner = new BackgroundTaskRunner<IBackgroundTask>("ScheduledPublishing", _logger, _hostingEnvironment);
|
||||
_tasksRunner = new BackgroundTaskRunner<IBackgroundTask>("ScheduledTasks", _logger, _hostingEnvironment);
|
||||
_scrubberRunner = new BackgroundTaskRunner<IBackgroundTask>("LogScrubber", _logger, _hostingEnvironment);
|
||||
_fileCleanupRunner = new BackgroundTaskRunner<IBackgroundTask>("TempFileCleanup", _logger, _hostingEnvironment);
|
||||
_healthCheckRunner = new BackgroundTaskRunner<IBackgroundTask>("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;
|
||||
}
|
||||
|
||||
@@ -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 IApplicationShutdownRegistry _hostingEnvironment;
|
||||
private static BackgroundTaskRunner<IBackgroundTask> _rebuildOnStartupRunner;
|
||||
|
||||
public BackgroundIndexRebuilder(IMainDom mainDom, IProfilingLogger logger, IHostingEnvironment hostingEnvironment, IndexRebuilder indexRebuilder)
|
||||
public BackgroundIndexRebuilder(IMainDom mainDom, IProfilingLogger logger, IApplicationShutdownRegistry hostingEnvironment, IndexRebuilder indexRebuilder)
|
||||
{
|
||||
_mainDom = mainDom;
|
||||
_logger = logger;
|
||||
@@ -32,8 +32,6 @@ namespace Umbraco.Web.Search
|
||||
/// <summary>
|
||||
/// Called to rebuild empty indexes on startup
|
||||
/// </summary>
|
||||
/// <param name="indexRebuilder"></param>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="onlyEmptyIndexes"></param>
|
||||
/// <param name="waitMilliseconds"></param>
|
||||
public void RebuildIndexes(bool onlyEmptyIndexes, int waitMilliseconds = 0)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 IApplicationShutdownRegistry _hostingLifetime;
|
||||
private readonly IIOHelper _ioHelper;
|
||||
private readonly ModelsGenerationError _errors;
|
||||
|
||||
@@ -51,12 +51,13 @@ namespace Umbraco.ModelsBuilder.Embedded
|
||||
IProfilingLogger logger,
|
||||
IModelsBuilderConfig config,
|
||||
IHostingEnvironment hostingEnvironment,
|
||||
IApplicationShutdownRegistry 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
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Umbraco.Tests.Common.Builders
|
||||
{
|
||||
public abstract class BuilderBase<T>
|
||||
{
|
||||
public abstract T Build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
namespace Umbraco.Tests.Common.Builders
|
||||
{
|
||||
public abstract class ChildBuilderBase<TParent, TType> : BuilderBase<TType>
|
||||
{
|
||||
private readonly TParent _parentBuilder;
|
||||
|
||||
protected ChildBuilderBase(TParent parentBuilder)
|
||||
{
|
||||
_parentBuilder = parentBuilder;
|
||||
}
|
||||
|
||||
|
||||
public TParent Done()
|
||||
{
|
||||
return _parentBuilder;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Tests.Common.Builders
|
||||
{
|
||||
public class ConfigurationEditorBuilder<TParent> : ChildBuilderBase<TParent, IConfigurationEditor>
|
||||
{
|
||||
private IDictionary<string, object> _defaultConfiguration;
|
||||
|
||||
|
||||
public ConfigurationEditorBuilder(TParent parentBuilder) : base(parentBuilder)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public ConfigurationEditorBuilder<TParent> WithDefaultConfiguration(IDictionary<string, object> defaultConfiguration)
|
||||
{
|
||||
_defaultConfiguration = defaultConfiguration;
|
||||
return this;
|
||||
}
|
||||
|
||||
public override IConfigurationEditor Build()
|
||||
{
|
||||
var defaultConfiguration = _defaultConfiguration ?? new Dictionary<string, object>();
|
||||
|
||||
return new ConfigurationEditor()
|
||||
{
|
||||
DefaultConfiguration = defaultConfiguration,
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using System.Collections.Generic;
|
||||
using Moq;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Strings;
|
||||
|
||||
namespace Umbraco.Tests.Common.Builders
|
||||
{
|
||||
public class DataEditorBuilder<TParent> : ChildBuilderBase<TParent, IDataEditor>
|
||||
{
|
||||
private readonly ConfigurationEditorBuilder<DataEditorBuilder<TParent>> _explicitConfigurationEditorBuilder;
|
||||
private readonly DataValueEditorBuilder<DataEditorBuilder<TParent>> _explicitValueEditorBuilder;
|
||||
private IDictionary<string, object> _defaultConfiguration;
|
||||
|
||||
public DataEditorBuilder(TParent parentBuilder) : base(parentBuilder)
|
||||
{
|
||||
_explicitConfigurationEditorBuilder = new ConfigurationEditorBuilder<DataEditorBuilder<TParent>>(this);
|
||||
_explicitValueEditorBuilder = new DataValueEditorBuilder<DataEditorBuilder<TParent>>(this);
|
||||
}
|
||||
|
||||
public DataEditorBuilder<TParent> WithDefaultConfiguration(IDictionary<string, object> defaultConfiguration)
|
||||
{
|
||||
_defaultConfiguration = defaultConfiguration;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConfigurationEditorBuilder<DataEditorBuilder<TParent>> AddExplicitConfigurationEditorBuilder() =>
|
||||
_explicitConfigurationEditorBuilder;
|
||||
|
||||
public DataValueEditorBuilder<DataEditorBuilder<TParent>> AddExplicitValueEditorBuilder() =>
|
||||
_explicitValueEditorBuilder;
|
||||
|
||||
public override IDataEditor Build()
|
||||
{
|
||||
var defaultConfiguration = _defaultConfiguration ?? new Dictionary<string, object>();
|
||||
var explicitConfigurationEditor = _explicitConfigurationEditorBuilder.Build();
|
||||
var explicitValueEditor = _explicitValueEditorBuilder.Build();
|
||||
|
||||
return new DataEditor(
|
||||
Mock.Of<ILogger>(),
|
||||
Mock.Of<IDataTypeService>(),
|
||||
Mock.Of<ILocalizationService>(),
|
||||
Mock.Of<ILocalizedTextService>(),
|
||||
Mock.Of<IShortStringHelper>()
|
||||
)
|
||||
{
|
||||
DefaultConfiguration = defaultConfiguration,
|
||||
ExplicitConfigurationEditor = explicitConfigurationEditor,
|
||||
ExplicitValueEditor = explicitValueEditor
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
using System;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Tests.Common.Builders.Interfaces;
|
||||
|
||||
namespace Umbraco.Tests.Common.Builders
|
||||
{
|
||||
public class DataTypeBuilder
|
||||
: BuilderBase<DataType>,
|
||||
IWithIdBuilder,
|
||||
IWithKeyBuilder,
|
||||
IWithCreateDateBuilder,
|
||||
IWithUpdateDateBuilder,
|
||||
IWithDeleteDateBuilder,
|
||||
IWithNameBuilder
|
||||
{
|
||||
private readonly DataEditorBuilder<DataTypeBuilder> _dataEditorBuilder;
|
||||
private int? _id;
|
||||
private int? _parentId;
|
||||
private Guid? _key;
|
||||
private DateTime? _createDate;
|
||||
private DateTime? _updateDate;
|
||||
private DateTime? _deleteDate;
|
||||
private string _name;
|
||||
private bool? _trashed;
|
||||
// private object _configuration;
|
||||
private int? _level;
|
||||
private string _path;
|
||||
private int? _creatorId;
|
||||
private ValueStorageType? _databaseType;
|
||||
private int? _sortOrder;
|
||||
|
||||
public DataTypeBuilder()
|
||||
{
|
||||
_dataEditorBuilder = new DataEditorBuilder<DataTypeBuilder>(this);
|
||||
}
|
||||
|
||||
public DataTypeBuilder WithParentId(int parentId)
|
||||
{
|
||||
_parentId = parentId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DataTypeBuilder WithTrashed(bool trashed)
|
||||
{
|
||||
_trashed = trashed;
|
||||
return this;
|
||||
}
|
||||
|
||||
// public DataTypeBuilder WithConfiguration(object configuration)
|
||||
// {
|
||||
// _configuration = configuration;
|
||||
// return this;
|
||||
// }
|
||||
|
||||
public DataTypeBuilder WithLevel(int level)
|
||||
{
|
||||
_level = level;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DataTypeBuilder WithPath(string path)
|
||||
{
|
||||
_path = path;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DataTypeBuilder WithCreatorId(int creatorId)
|
||||
{
|
||||
_creatorId = creatorId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DataTypeBuilder WithDatabaseType(ValueStorageType databaseType)
|
||||
{
|
||||
_databaseType = databaseType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DataTypeBuilder WithSortOrder(int sortOrder)
|
||||
{
|
||||
_sortOrder = sortOrder;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DataEditorBuilder<DataTypeBuilder> AddEditor()
|
||||
{
|
||||
return _dataEditorBuilder;
|
||||
}
|
||||
|
||||
public override DataType Build()
|
||||
{
|
||||
var editor = _dataEditorBuilder.Build();
|
||||
var parentId = _parentId ?? -1;
|
||||
var id = _id ?? 1;
|
||||
var key = _key ?? Guid.NewGuid();
|
||||
var createDate = _createDate ?? DateTime.Now;
|
||||
var updateDate = _updateDate ?? DateTime.Now;
|
||||
var deleteDate = _deleteDate ?? null;
|
||||
var name = _name ?? Guid.NewGuid().ToString();
|
||||
// var configuration = _configuration ?? editor.GetConfigurationEditor().DefaultConfigurationObject;
|
||||
var level = _level ?? 0;
|
||||
var path = _path ?? string.Empty;
|
||||
var creatorId = _creatorId ?? 1;
|
||||
var databaseType = _databaseType ?? ValueStorageType.Ntext;
|
||||
var sortOrder = _sortOrder ?? 0;
|
||||
|
||||
return new DataType(editor, parentId)
|
||||
{
|
||||
Id = id,
|
||||
Key = key,
|
||||
CreateDate = createDate,
|
||||
UpdateDate = updateDate,
|
||||
DeleteDate = deleteDate,
|
||||
Name = name,
|
||||
Trashed = _trashed ?? false,
|
||||
Level = level,
|
||||
Path = path,
|
||||
CreatorId = creatorId,
|
||||
DatabaseType = databaseType,
|
||||
SortOrder = sortOrder,
|
||||
};
|
||||
}
|
||||
|
||||
int? IWithIdBuilder.Id
|
||||
{
|
||||
get => _id;
|
||||
set => _id = value;
|
||||
}
|
||||
|
||||
Guid? IWithKeyBuilder.Key
|
||||
{
|
||||
get => _key;
|
||||
set => _key = value;
|
||||
}
|
||||
|
||||
DateTime? IWithCreateDateBuilder.CreateDate
|
||||
{
|
||||
get => _createDate;
|
||||
set => _createDate = value;
|
||||
}
|
||||
|
||||
DateTime? IWithUpdateDateBuilder.UpdateDate
|
||||
{
|
||||
get => _updateDate;
|
||||
set => _updateDate = value;
|
||||
}
|
||||
|
||||
DateTime? IWithDeleteDateBuilder.DeleteDate
|
||||
{
|
||||
get => _deleteDate;
|
||||
set => _deleteDate = value;
|
||||
}
|
||||
|
||||
string IWithNameBuilder.Name
|
||||
{
|
||||
get => _name;
|
||||
set => _name = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using Moq;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Strings;
|
||||
|
||||
namespace Umbraco.Tests.Common.Builders
|
||||
{
|
||||
public class DataValueEditorBuilder<TParent> : ChildBuilderBase<TParent, IDataValueEditor>
|
||||
{
|
||||
private string _configuration;
|
||||
private string _view;
|
||||
private bool? _hideLabel;
|
||||
private string _valueType;
|
||||
|
||||
|
||||
public DataValueEditorBuilder(TParent parentBuilder) : base(parentBuilder)
|
||||
{
|
||||
}
|
||||
|
||||
public DataValueEditorBuilder<TParent> WithConfiguration(string configuration)
|
||||
{
|
||||
_configuration = configuration;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DataValueEditorBuilder<TParent> WithView(string view)
|
||||
{
|
||||
_view = view;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DataValueEditorBuilder<TParent> WithHideLabel(bool hideLabel)
|
||||
{
|
||||
_hideLabel = hideLabel;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DataValueEditorBuilder<TParent> WithValueType(string valueType)
|
||||
{
|
||||
_valueType = valueType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public override IDataValueEditor Build()
|
||||
{
|
||||
var configuration = _configuration ?? null;
|
||||
var view = _view ?? null;
|
||||
var hideLabel = _hideLabel ?? false;
|
||||
var valueType = _valueType ?? Guid.NewGuid().ToString();
|
||||
|
||||
return new DataValueEditor(
|
||||
Mock.Of<IDataTypeService>(),
|
||||
Mock.Of<ILocalizationService>(),
|
||||
Mock.Of<ILocalizedTextService>(),
|
||||
Mock.Of<IShortStringHelper>()
|
||||
)
|
||||
{
|
||||
Configuration = configuration,
|
||||
View = view,
|
||||
HideLabel = hideLabel,
|
||||
ValueType = valueType,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Tests.Common.Builders.Interfaces;
|
||||
|
||||
namespace Umbraco.Tests.Common.Builders
|
||||
{
|
||||
public class DictionaryItemBuilder
|
||||
: BuilderBase<DictionaryItem>,
|
||||
IWithIdBuilder,
|
||||
IWithCreateDateBuilder,
|
||||
IWithUpdateDateBuilder,
|
||||
IWithDeleteDateBuilder,
|
||||
IWithKeyBuilder
|
||||
{
|
||||
private readonly List<DictionaryTranslationBuilder> _translationBuilders =
|
||||
new List<DictionaryTranslationBuilder>();
|
||||
|
||||
private DateTime? _createDate;
|
||||
private DateTime? _deleteDate;
|
||||
private int? _id;
|
||||
private string _itemKey;
|
||||
private Guid? _key;
|
||||
private Guid? _parentId;
|
||||
private DateTime? _updateDate;
|
||||
|
||||
DateTime? IWithCreateDateBuilder.CreateDate
|
||||
{
|
||||
get => _createDate;
|
||||
set => _createDate = value;
|
||||
}
|
||||
|
||||
DateTime? IWithDeleteDateBuilder.DeleteDate
|
||||
{
|
||||
get => _deleteDate;
|
||||
set => _deleteDate = value;
|
||||
}
|
||||
|
||||
int? IWithIdBuilder.Id
|
||||
{
|
||||
get => _id;
|
||||
set => _id = value;
|
||||
}
|
||||
|
||||
Guid? IWithKeyBuilder.Key
|
||||
{
|
||||
get => _key;
|
||||
set => _key = value;
|
||||
}
|
||||
|
||||
DateTime? IWithUpdateDateBuilder.UpdateDate
|
||||
{
|
||||
get => _updateDate;
|
||||
set => _updateDate = value;
|
||||
}
|
||||
|
||||
public override DictionaryItem Build()
|
||||
{
|
||||
var createDate = _createDate ?? DateTime.Now;
|
||||
var updateDate = _updateDate ?? DateTime.Now;
|
||||
var deleteDate = _deleteDate ?? null;
|
||||
var id = _id ?? 1;
|
||||
var key = _key ?? Guid.NewGuid();
|
||||
var parentId = _parentId ?? null;
|
||||
var itemKey = _itemKey ?? Guid.NewGuid().ToString();
|
||||
|
||||
var result = new DictionaryItem(itemKey)
|
||||
{
|
||||
Translations = _translationBuilders.Select(x => x.Build()),
|
||||
CreateDate = createDate,
|
||||
UpdateDate = updateDate,
|
||||
DeleteDate = deleteDate,
|
||||
Id = id,
|
||||
ParentId = parentId,
|
||||
Key = key,
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
public DictionaryItemBuilder WithParentId(Guid parentId)
|
||||
{
|
||||
_parentId = parentId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DictionaryItemBuilder WithItemKey(string itemKey)
|
||||
{
|
||||
_itemKey = itemKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DictionaryTranslationBuilder AddTranslation()
|
||||
{
|
||||
var builder = new DictionaryTranslationBuilder(this);
|
||||
|
||||
_translationBuilders.Add(builder);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
public DictionaryItemBuilder WithRandomTranslations(int count)
|
||||
{
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
AddTranslation().Done();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
using System;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Tests.Common.Builders.Interfaces;
|
||||
|
||||
namespace Umbraco.Tests.Common.Builders
|
||||
{
|
||||
public class DictionaryTranslationBuilder
|
||||
: ChildBuilderBase<DictionaryItemBuilder, IDictionaryTranslation>,
|
||||
IWithIdBuilder,
|
||||
IWithCreateDateBuilder,
|
||||
IWithUpdateDateBuilder,
|
||||
IWithDeleteDateBuilder,
|
||||
IWithKeyBuilder
|
||||
{
|
||||
private readonly LanguageBuilder<DictionaryTranslationBuilder> _languageBuilder;
|
||||
private readonly Guid? _uniqueId = null;
|
||||
private DateTime? _createDate;
|
||||
private DateTime? _deleteDate;
|
||||
private int? _id;
|
||||
private Guid? _key;
|
||||
private DateTime? _updateDate;
|
||||
private string _value;
|
||||
|
||||
|
||||
public DictionaryTranslationBuilder(DictionaryItemBuilder parentBuilder) : base(parentBuilder)
|
||||
{
|
||||
_languageBuilder = new LanguageBuilder<DictionaryTranslationBuilder>(this);
|
||||
}
|
||||
|
||||
DateTime? IWithCreateDateBuilder.CreateDate
|
||||
{
|
||||
get => _createDate;
|
||||
set => _createDate = value;
|
||||
}
|
||||
|
||||
DateTime? IWithDeleteDateBuilder.DeleteDate
|
||||
{
|
||||
get => _deleteDate;
|
||||
set => _deleteDate = value;
|
||||
}
|
||||
|
||||
int? IWithIdBuilder.Id
|
||||
{
|
||||
get => _id;
|
||||
set => _id = value;
|
||||
}
|
||||
|
||||
Guid? IWithKeyBuilder.Key
|
||||
{
|
||||
get => _key;
|
||||
set => _key = value;
|
||||
}
|
||||
|
||||
DateTime? IWithUpdateDateBuilder.UpdateDate
|
||||
{
|
||||
get => _updateDate;
|
||||
set => _updateDate = value;
|
||||
}
|
||||
|
||||
public override IDictionaryTranslation Build()
|
||||
{
|
||||
var createDate = _createDate ?? DateTime.Now;
|
||||
var updateDate = _updateDate ?? DateTime.Now;
|
||||
var deleteDate = _deleteDate ?? null;
|
||||
var id = _id ?? 1;
|
||||
var key = _key ?? Guid.NewGuid();
|
||||
|
||||
var result = new DictionaryTranslation(
|
||||
_languageBuilder.Build(),
|
||||
_value ?? Guid.NewGuid().ToString(),
|
||||
_uniqueId ?? key)
|
||||
{
|
||||
CreateDate = createDate,
|
||||
UpdateDate = updateDate,
|
||||
DeleteDate = deleteDate,
|
||||
Id = id
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public LanguageBuilder<DictionaryTranslationBuilder> AddLanguage() => _languageBuilder;
|
||||
|
||||
public DictionaryTranslationBuilder WithValue(string value)
|
||||
{
|
||||
_value = value;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using Umbraco.Tests.Common.Builders.Interfaces;
|
||||
|
||||
namespace Umbraco.Tests.Common.Builders.Extensions
|
||||
{
|
||||
public static class BuilderExtensions
|
||||
{
|
||||
public static T WithId<T>(this T builder, int id)
|
||||
where T : IWithIdBuilder
|
||||
{
|
||||
builder.Id = id;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static T WithCreateDate<T>(this T builder, DateTime createDate)
|
||||
where T : IWithCreateDateBuilder
|
||||
{
|
||||
builder.CreateDate = createDate;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static T WithUpdateDate<T>(this T builder, DateTime updateDate)
|
||||
where T : IWithUpdateDateBuilder
|
||||
{
|
||||
builder.UpdateDate = updateDate;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static T WithAlias<T>(this T builder, string alias)
|
||||
where T : IWithAliasBuilder
|
||||
{
|
||||
builder.Alias = alias;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static T WithName<T>(this T builder, string name)
|
||||
where T : IWithNameBuilder
|
||||
{
|
||||
builder.Name = name;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static T WithKey<T>(this T builder, Guid key)
|
||||
where T : IWithKeyBuilder
|
||||
{
|
||||
builder.Key = key;
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,249 @@
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Tests.Common.Builders
|
||||
{
|
||||
public class GlobalSettingsBuilder : GlobalSettingsBuilder<object>
|
||||
{
|
||||
public GlobalSettingsBuilder() : base(null)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class GlobalSettingsBuilder<TParent> : ChildBuilderBase<TParent, IGlobalSettings>
|
||||
{
|
||||
private string _configurationStatus;
|
||||
private string _databaseFactoryServerVersion;
|
||||
private string _defaultUiLanguage;
|
||||
private bool? _disableElectionForSingleServer;
|
||||
private bool? _hideTopLevelNodeFromPath;
|
||||
private bool? _installEmptyDatabase;
|
||||
private bool? _installMissingDatabase;
|
||||
private bool? _isSmtpServerConfigured;
|
||||
private string _path;
|
||||
private string _registerType;
|
||||
private string _reservedPaths;
|
||||
private string _reservedUrls;
|
||||
private int? _timeOutInMinutes;
|
||||
private string _umbracoCssPath;
|
||||
private string _umbracoMediaPath;
|
||||
private string _umbracoPath;
|
||||
private string _umbracoScriptsPath;
|
||||
private string _mainDomLock;
|
||||
private string _noNodesViewPath;
|
||||
private bool? _useHttps;
|
||||
private int? _versionCheckPeriod;
|
||||
private readonly SmtpSettingsBuilder<GlobalSettingsBuilder<TParent>> _smtpSettingsBuilder;
|
||||
|
||||
|
||||
public GlobalSettingsBuilder(TParent parentBuilder) : base(parentBuilder)
|
||||
{
|
||||
_smtpSettingsBuilder = new SmtpSettingsBuilder<GlobalSettingsBuilder<TParent>>(this);
|
||||
}
|
||||
|
||||
public SmtpSettingsBuilder<GlobalSettingsBuilder<TParent>> AddSmtpSettings() => _smtpSettingsBuilder;
|
||||
|
||||
public GlobalSettingsBuilder<TParent> WithConfigurationStatus(string configurationStatus)
|
||||
{
|
||||
_configurationStatus = configurationStatus;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GlobalSettingsBuilder<TParent> WithDatabaseFactoryServerVersion(string databaseFactoryServerVersion)
|
||||
{
|
||||
_databaseFactoryServerVersion = databaseFactoryServerVersion;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GlobalSettingsBuilder<TParent> WithDefaultUiLanguage(string defaultUiLanguage)
|
||||
{
|
||||
_defaultUiLanguage = defaultUiLanguage;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GlobalSettingsBuilder<TParent> WithDisableElectionForSingleServer(bool disableElectionForSingleServer)
|
||||
{
|
||||
_disableElectionForSingleServer = disableElectionForSingleServer;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GlobalSettingsBuilder<TParent> WithHideTopLevelNodeFromPath(bool hideTopLevelNodeFromPath)
|
||||
{
|
||||
_hideTopLevelNodeFromPath = hideTopLevelNodeFromPath;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GlobalSettingsBuilder<TParent> WithInstallEmptyDatabase(bool installEmptyDatabase)
|
||||
{
|
||||
_installEmptyDatabase = installEmptyDatabase;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GlobalSettingsBuilder<TParent> WithInstallMissingDatabase(bool installMissingDatabase)
|
||||
{
|
||||
_installMissingDatabase = installMissingDatabase;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GlobalSettingsBuilder<TParent> WithIsSmtpServerConfigured(bool isSmtpServerConfigured)
|
||||
{
|
||||
_isSmtpServerConfigured = isSmtpServerConfigured;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GlobalSettingsBuilder<TParent> WithPath(string path)
|
||||
{
|
||||
_path = path;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GlobalSettingsBuilder<TParent> WithRegisterType(string registerType)
|
||||
{
|
||||
_registerType = registerType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GlobalSettingsBuilder<TParent> WithReservedPaths(string reservedPaths)
|
||||
{
|
||||
_reservedPaths = reservedPaths;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GlobalSettingsBuilder<TParent> WithReservedUrls(string reservedUrls)
|
||||
{
|
||||
_reservedUrls = reservedUrls;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GlobalSettingsBuilder<TParent> WithUmbracoPath(string umbracoPath)
|
||||
{
|
||||
_umbracoPath = umbracoPath;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GlobalSettingsBuilder<TParent> WithUseHttps(bool useHttps)
|
||||
{
|
||||
_useHttps = useHttps;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GlobalSettingsBuilder<TParent> WithUmbracoCssPath(string umbracoCssPath)
|
||||
{
|
||||
_umbracoCssPath = umbracoCssPath;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GlobalSettingsBuilder<TParent> WithUmbracoMediaPath(string umbracoMediaPath)
|
||||
{
|
||||
_umbracoMediaPath = umbracoMediaPath;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GlobalSettingsBuilder<TParent> WithUmbracoScriptsPath(string umbracoScriptsPath)
|
||||
{
|
||||
_umbracoScriptsPath = umbracoScriptsPath;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GlobalSettingsBuilder<TParent> WithMainDomLock(string mainDomLock)
|
||||
{
|
||||
_mainDomLock = mainDomLock;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GlobalSettingsBuilder<TParent> WithNoNodesViewPath(string noNodesViewPath)
|
||||
{
|
||||
_noNodesViewPath = noNodesViewPath;
|
||||
return this;
|
||||
}
|
||||
public GlobalSettingsBuilder<TParent> WithVersionCheckPeriod(int versionCheckPeriod)
|
||||
{
|
||||
_versionCheckPeriod = versionCheckPeriod;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GlobalSettingsBuilder<TParent> WithTimeOutInMinutes(int timeOutInMinutes)
|
||||
{
|
||||
_timeOutInMinutes = timeOutInMinutes;
|
||||
return this;
|
||||
}
|
||||
|
||||
public override IGlobalSettings Build()
|
||||
{
|
||||
var configurationStatus = _configurationStatus ?? "9.0.0";
|
||||
var databaseFactoryServerVersion = _databaseFactoryServerVersion ?? null;
|
||||
var defaultUiLanguage = _defaultUiLanguage ?? "en";
|
||||
var disableElectionForSingleServer = _disableElectionForSingleServer ?? false;
|
||||
var hideTopLevelNodeFromPath = _hideTopLevelNodeFromPath ?? false;
|
||||
var installEmptyDatabase = _installEmptyDatabase ?? false;
|
||||
var installMissingDatabase = _installMissingDatabase ?? false;
|
||||
var isSmtpServerConfigured = _isSmtpServerConfigured ?? false;
|
||||
var path = _path ?? "/umbraco";
|
||||
var registerType = _registerType ?? null;
|
||||
var reservedPaths = _reservedPaths ?? "~/app_plugins/,~/install/,~/mini-profiler-resources/,";
|
||||
var reservedUrls = _reservedUrls ?? "~/config/splashes/noNodes.aspx,~/.well-known,";
|
||||
var umbracoPath = _umbracoPath ?? "~/umbraco";
|
||||
var useHttps = _useHttps ?? false;
|
||||
var umbracoCssPath = _umbracoCssPath ?? "~/css";
|
||||
var umbracoMediaPath = _umbracoMediaPath ?? "~/media";
|
||||
var umbracoScriptsPath = _umbracoScriptsPath ?? "~/scripts";
|
||||
var versionCheckPeriod = _versionCheckPeriod ?? 0;
|
||||
var timeOutInMinutes = _timeOutInMinutes ?? 20;
|
||||
var smtpSettings = _smtpSettingsBuilder.Build();
|
||||
var mainDomLock = _mainDomLock ?? string.Empty;
|
||||
var noNodesViewPath = _noNodesViewPath ?? "~/config/splashes/NoNodes.cshtml";
|
||||
|
||||
|
||||
return new TestGlobalSettings
|
||||
{
|
||||
ConfigurationStatus = configurationStatus,
|
||||
DatabaseFactoryServerVersion = databaseFactoryServerVersion,
|
||||
DefaultUILanguage = defaultUiLanguage,
|
||||
DisableElectionForSingleServer = disableElectionForSingleServer,
|
||||
HideTopLevelNodeFromPath = hideTopLevelNodeFromPath,
|
||||
InstallEmptyDatabase = installEmptyDatabase,
|
||||
InstallMissingDatabase = installMissingDatabase,
|
||||
IsSmtpServerConfigured = isSmtpServerConfigured,
|
||||
Path = path,
|
||||
RegisterType = registerType,
|
||||
ReservedPaths = reservedPaths,
|
||||
ReservedUrls = reservedUrls,
|
||||
UmbracoPath = umbracoPath,
|
||||
UseHttps = useHttps,
|
||||
UmbracoCssPath = umbracoCssPath,
|
||||
UmbracoMediaPath = umbracoMediaPath,
|
||||
UmbracoScriptsPath = umbracoScriptsPath,
|
||||
VersionCheckPeriod = versionCheckPeriod,
|
||||
TimeOutInMinutes = timeOutInMinutes,
|
||||
SmtpSettings = smtpSettings,
|
||||
MainDomLock = mainDomLock,
|
||||
NoNodesViewPath = noNodesViewPath,
|
||||
};
|
||||
}
|
||||
|
||||
private class TestGlobalSettings : IGlobalSettings
|
||||
{
|
||||
public string ReservedUrls { get; set; }
|
||||
public string ReservedPaths { get; set; }
|
||||
public string Path { get; set; }
|
||||
public string ConfigurationStatus { get; set; }
|
||||
public int TimeOutInMinutes { get; set; }
|
||||
public string DefaultUILanguage { get; set; }
|
||||
public bool HideTopLevelNodeFromPath { get; set; }
|
||||
public bool UseHttps { get; set; }
|
||||
public int VersionCheckPeriod { get; set; }
|
||||
public string UmbracoPath { get; set; }
|
||||
public string UmbracoCssPath { get; set; }
|
||||
public string UmbracoScriptsPath { get; set; }
|
||||
public string UmbracoMediaPath { get; set; }
|
||||
public bool IsSmtpServerConfigured { get; set; }
|
||||
public ISmtpSettings SmtpSettings { get; set; }
|
||||
public bool InstallMissingDatabase { get; set; }
|
||||
public bool InstallEmptyDatabase { get; set; }
|
||||
public bool DisableElectionForSingleServer { get; set; }
|
||||
public string RegisterType { get; set; }
|
||||
public string DatabaseFactoryServerVersion { get; set; }
|
||||
public string MainDomLock { get; set; }
|
||||
public string NoNodesViewPath { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Umbraco.Tests.Common.Builders.Interfaces
|
||||
{
|
||||
public interface IWithAliasBuilder
|
||||
{
|
||||
string Alias { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Tests.Common.Builders.Interfaces
|
||||
{
|
||||
public interface IWithCreateDateBuilder
|
||||
{
|
||||
DateTime? CreateDate { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System.Globalization;
|
||||
|
||||
namespace Umbraco.Tests.Common.Builders.Interfaces
|
||||
{
|
||||
public interface IWithCultureInfoBuilder
|
||||
{
|
||||
CultureInfo CultureInfo { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Tests.Common.Builders.Interfaces
|
||||
{
|
||||
public interface IWithDeleteDateBuilder
|
||||
{
|
||||
DateTime? DeleteDate { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Umbraco.Tests.Common.Builders.Interfaces
|
||||
{
|
||||
public interface IWithIdBuilder
|
||||
{
|
||||
int? Id { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Tests.Common.Builders.Interfaces
|
||||
{
|
||||
public interface IWithKeyBuilder
|
||||
{
|
||||
Guid? Key { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Umbraco.Tests.Common.Builders.Interfaces
|
||||
{
|
||||
public interface IWithNameBuilder
|
||||
{
|
||||
string Name { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Tests.Common.Builders.Interfaces
|
||||
{
|
||||
public interface IWithUpdateDateBuilder
|
||||
{
|
||||
DateTime? UpdateDate { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Moq;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Tests.Common.Builders.Interfaces;
|
||||
|
||||
namespace Umbraco.Tests.Common.Builders
|
||||
{
|
||||
public class LanguageBuilder : LanguageBuilder<object>
|
||||
{
|
||||
public LanguageBuilder() : base(null)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class LanguageBuilder<TParent>
|
||||
: ChildBuilderBase<TParent, ILanguage>,
|
||||
IWithIdBuilder,
|
||||
IWithKeyBuilder,
|
||||
IWithCreateDateBuilder,
|
||||
IWithUpdateDateBuilder,
|
||||
IWithDeleteDateBuilder,
|
||||
IWithCultureInfoBuilder
|
||||
{
|
||||
private DateTime? _createDate;
|
||||
private CultureInfo _cultureInfo;
|
||||
private DateTime? _deleteDate;
|
||||
private int? _fallbackLanguageId;
|
||||
private int? _id;
|
||||
private bool? _isDefault;
|
||||
private bool? _isMandatory;
|
||||
private Guid? _key;
|
||||
private DateTime? _updateDate;
|
||||
|
||||
public LanguageBuilder(TParent parentBuilder) : base(parentBuilder)
|
||||
{
|
||||
}
|
||||
|
||||
DateTime? IWithCreateDateBuilder.CreateDate
|
||||
{
|
||||
get => _createDate;
|
||||
set => _createDate = value;
|
||||
}
|
||||
|
||||
CultureInfo IWithCultureInfoBuilder.CultureInfo
|
||||
{
|
||||
get => _cultureInfo;
|
||||
set => _cultureInfo = value;
|
||||
}
|
||||
|
||||
DateTime? IWithDeleteDateBuilder.DeleteDate
|
||||
{
|
||||
get => _deleteDate;
|
||||
set => _deleteDate = value;
|
||||
}
|
||||
|
||||
int? IWithIdBuilder.Id
|
||||
{
|
||||
get => _id;
|
||||
set => _id = value;
|
||||
}
|
||||
|
||||
Guid? IWithKeyBuilder.Key
|
||||
{
|
||||
get => _key;
|
||||
set => _key = value;
|
||||
}
|
||||
|
||||
DateTime? IWithUpdateDateBuilder.UpdateDate
|
||||
{
|
||||
get => _updateDate;
|
||||
set => _updateDate = value;
|
||||
}
|
||||
|
||||
public override ILanguage Build()
|
||||
{
|
||||
var cultureInfo = _cultureInfo ?? CultureInfo.GetCultureInfo("en-US");
|
||||
var key = _key ?? Guid.NewGuid();
|
||||
var createDate = _createDate ?? DateTime.Now;
|
||||
var updateDate = _updateDate ?? DateTime.Now;
|
||||
var deleteDate = _deleteDate ?? null;
|
||||
var fallbackLanguageId = _fallbackLanguageId ?? null;
|
||||
var isDefault = _isDefault ?? false;
|
||||
var isMandatory = _isMandatory ?? false;
|
||||
|
||||
return new Language(Mock.Of<IGlobalSettings>(), cultureInfo.Name)
|
||||
{
|
||||
Id = _id ?? 1,
|
||||
CultureName = cultureInfo.TwoLetterISOLanguageName,
|
||||
IsoCode = new RegionInfo(cultureInfo.LCID).Name,
|
||||
Key = key,
|
||||
CreateDate = createDate,
|
||||
UpdateDate = updateDate,
|
||||
DeleteDate = deleteDate,
|
||||
IsDefault = isDefault,
|
||||
IsMandatory = isMandatory,
|
||||
FallbackLanguageId = fallbackLanguageId
|
||||
};
|
||||
}
|
||||
|
||||
public LanguageBuilder<TParent> WithIsDefault(bool isDefault)
|
||||
{
|
||||
_isDefault = isDefault;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LanguageBuilder<TParent> WithIsMandatory(bool isMandatory)
|
||||
{
|
||||
_isMandatory = isMandatory;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LanguageBuilder<TParent> WithFallbackLanguageId(int fallbackLanguageId)
|
||||
{
|
||||
_fallbackLanguageId = fallbackLanguageId;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
using System;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Tests.Common.Builders.Interfaces;
|
||||
|
||||
namespace Umbraco.Tests.Common.Builders
|
||||
{
|
||||
public class RelationTypeBuilder : RelationTypeBuilder<object>
|
||||
{
|
||||
public RelationTypeBuilder() : base(null)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class RelationTypeBuilder<TParent>
|
||||
: ChildBuilderBase<TParent, IRelationType>,
|
||||
IWithIdBuilder,
|
||||
IWithAliasBuilder,
|
||||
IWithNameBuilder,
|
||||
IWithKeyBuilder,
|
||||
IWithCreateDateBuilder,
|
||||
IWithUpdateDateBuilder,
|
||||
IWithDeleteDateBuilder
|
||||
{
|
||||
private string _alias;
|
||||
private Guid? _childObjectType;
|
||||
private DateTime? _createDate;
|
||||
private DateTime? _deleteDate;
|
||||
private int? _id;
|
||||
private bool? _isBidirectional;
|
||||
private Guid? _key;
|
||||
private string _name;
|
||||
private Guid? _parentObjectType;
|
||||
private DateTime? _updateDate;
|
||||
|
||||
public RelationTypeBuilder(TParent parentBuilder) : base(parentBuilder)
|
||||
{
|
||||
}
|
||||
|
||||
string IWithAliasBuilder.Alias
|
||||
{
|
||||
get => _alias;
|
||||
set => _alias = value;
|
||||
}
|
||||
|
||||
DateTime? IWithCreateDateBuilder.CreateDate
|
||||
{
|
||||
get => _createDate;
|
||||
set => _createDate = value;
|
||||
}
|
||||
|
||||
DateTime? IWithDeleteDateBuilder.DeleteDate
|
||||
{
|
||||
get => _deleteDate;
|
||||
set => _deleteDate = value;
|
||||
}
|
||||
|
||||
int? IWithIdBuilder.Id
|
||||
{
|
||||
get => _id;
|
||||
set => _id = value;
|
||||
}
|
||||
|
||||
Guid? IWithKeyBuilder.Key
|
||||
{
|
||||
get => _key;
|
||||
set => _key = value;
|
||||
}
|
||||
|
||||
string IWithNameBuilder.Name
|
||||
{
|
||||
get => _name;
|
||||
set => _name = value;
|
||||
}
|
||||
|
||||
DateTime? IWithUpdateDateBuilder.UpdateDate
|
||||
{
|
||||
get => _updateDate;
|
||||
set => _updateDate = value;
|
||||
}
|
||||
|
||||
public override IRelationType Build()
|
||||
{
|
||||
var alias = _alias ?? Guid.NewGuid().ToString();
|
||||
var name = _name ?? Guid.NewGuid().ToString();
|
||||
var parentObjectType = _parentObjectType ?? null;
|
||||
var childObjectType = _childObjectType ?? null;
|
||||
var id = _id ?? 1;
|
||||
var key = _key ?? Guid.NewGuid();
|
||||
var isBidirectional = _isBidirectional ?? false;
|
||||
var createDate = _createDate ?? DateTime.Now;
|
||||
var updateDate = _updateDate ?? DateTime.Now;
|
||||
var deleteDate = _deleteDate ?? null;
|
||||
|
||||
return new RelationType(name, alias, isBidirectional, parentObjectType,
|
||||
childObjectType)
|
||||
{
|
||||
Id = id,
|
||||
Key = key,
|
||||
CreateDate = createDate,
|
||||
UpdateDate = updateDate,
|
||||
DeleteDate = deleteDate
|
||||
};
|
||||
}
|
||||
|
||||
public RelationTypeBuilder<TParent> WithIsBidirectional(bool isBidirectional)
|
||||
{
|
||||
_isBidirectional = isBidirectional;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RelationTypeBuilder<TParent> WithChildObjectType(Guid childObjectType)
|
||||
{
|
||||
_childObjectType = childObjectType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RelationTypeBuilder<TParent> WithParentObjectType(Guid parentObjectType)
|
||||
{
|
||||
_parentObjectType = parentObjectType;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Tests.Common.Builders
|
||||
{
|
||||
public class SmtpSettingsBuilder : SmtpSettingsBuilder<object>
|
||||
{
|
||||
public SmtpSettingsBuilder() : base(null)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class SmtpSettingsBuilder<TParent>
|
||||
: ChildBuilderBase<TParent, ISmtpSettings>
|
||||
{
|
||||
private string _from;
|
||||
private string _host;
|
||||
private int? _port;
|
||||
private string _pickupDirectoryLocation;
|
||||
|
||||
public SmtpSettingsBuilder(TParent parentBuilder) : base(parentBuilder)
|
||||
{
|
||||
}
|
||||
|
||||
public SmtpSettingsBuilder<TParent> WithFrom(string from)
|
||||
{
|
||||
_from = from;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SmtpSettingsBuilder<TParent> WithHost(string host)
|
||||
{
|
||||
_host = host;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SmtpSettingsBuilder<TParent> WithPost(int port)
|
||||
{
|
||||
_port = port;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SmtpSettingsBuilder<TParent> WithPickupDirectoryLocation(string pickupDirectoryLocation)
|
||||
{
|
||||
_pickupDirectoryLocation = pickupDirectoryLocation;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public override ISmtpSettings Build()
|
||||
{
|
||||
var from = _from ?? null;
|
||||
var host = _host ?? null;
|
||||
var port = _port ?? 25;
|
||||
var pickupDirectoryLocation = _pickupDirectoryLocation ?? null;
|
||||
|
||||
return new TestSmtpSettings()
|
||||
{
|
||||
From = from,
|
||||
Host = host,
|
||||
Port = port,
|
||||
PickupDirectoryLocation = pickupDirectoryLocation,
|
||||
};
|
||||
}
|
||||
|
||||
private class TestSmtpSettings : ISmtpSettings
|
||||
{
|
||||
public string From { get; set; }
|
||||
public string Host { get; set; }
|
||||
public int Port { get; set; }
|
||||
public string PickupDirectoryLocation { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,11 +12,11 @@ using Umbraco.Core.Hosting;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.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<ILogger>(),
|
||||
Mock.Of<IGlobalSettings>(),
|
||||
new Lazy<IMainDom>(),
|
||||
new Lazy<IServerRegistrar>(),
|
||||
GetUmbracoVersion(),
|
||||
GetHostingEnvironment(),
|
||||
GetBackOfficeInfo()
|
||||
);
|
||||
GetBackOfficeInfo());
|
||||
}
|
||||
|
||||
public abstract IBackOfficeInfo GetBackOfficeInfo();
|
||||
@@ -132,6 +128,7 @@ namespace Umbraco.Tests.Common
|
||||
}
|
||||
|
||||
public abstract IHostingEnvironment GetHostingEnvironment();
|
||||
public abstract IApplicationShutdownRegistry GetHostingEnvironmentLifetime();
|
||||
|
||||
public abstract IIpResolver GetIpResolver();
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using LightInject;
|
||||
using System.Threading.Tasks;
|
||||
using LightInject;
|
||||
using LightInject.Microsoft.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
@@ -37,7 +38,7 @@ namespace Umbraco.Tests.Integration
|
||||
var testHelper = new TestHelper();
|
||||
var runtimeState = Mock.Of<IRuntimeState>();
|
||||
var umbracoDatabaseFactory = Mock.Of<IUmbracoDatabaseFactory>();
|
||||
var dbProviderFactoryCreator = Mock.Of<IDbProviderFactoryCreator>();
|
||||
var dbProviderFactoryCreator = Mock.Of<IDbProviderFactoryCreator>();
|
||||
var typeLoader = testHelper.GetMockedTypeLoader();
|
||||
|
||||
// Register in the container
|
||||
@@ -45,7 +46,8 @@ namespace Umbraco.Tests.Integration
|
||||
testHelper.Logger, runtimeState, testHelper.GetConfigs(), testHelper.IOHelper, testHelper.AppCaches);
|
||||
composition.RegisterEssentials(testHelper.Logger, testHelper.Profiler, testHelper.Logger, testHelper.MainDom,
|
||||
testHelper.AppCaches, umbracoDatabaseFactory, typeLoader, runtimeState, testHelper.GetTypeFinder(),
|
||||
testHelper.IOHelper, testHelper.GetUmbracoVersion(), dbProviderFactoryCreator);
|
||||
testHelper.IOHelper, testHelper.GetUmbracoVersion(), dbProviderFactoryCreator,
|
||||
testHelper.GetHostingEnvironment(), testHelper.GetBackOfficeInfo());
|
||||
|
||||
// Cross wire - this would be called by the Host Builder at the very end of ConfigureServices
|
||||
var lightInjectServiceProvider = serviceProviderFactory.CreateServiceProvider(umbracoContainer.Container);
|
||||
@@ -67,6 +69,46 @@ namespace Umbraco.Tests.Integration
|
||||
Assertions.AssertContainer(umbracoContainer.Container);
|
||||
}
|
||||
|
||||
[Explicit("This test just shows that resolving services from the container before the host is done resolves 2 different instances")]
|
||||
[Test]
|
||||
public async Task BuildServiceProvider_Before_Host_Is_Configured()
|
||||
{
|
||||
// This is a test to show an anti-pattern used in netcore. This should be avoided in all cases if possible.
|
||||
// There's a thread about this here: https://github.com/dotnet/aspnetcore/issues/14587
|
||||
// For some reason we are not being warned about this with our code analysis since we are using it
|
||||
// in a couple of places but we should really try to see if we can avoid it.
|
||||
// The test below shows how it could be possible to resolve an instance and then re-register it as a factory
|
||||
// so that only one singleton instance is every created, but it's hacky and like Fowler says in that article
|
||||
// it means the container won't be disposed, and maybe other services? not sure.
|
||||
// In cases where we use it can we use IConfigureOptions? https://andrewlock.net/access-services-inside-options-and-startup-using-configureoptions/
|
||||
|
||||
var umbracoContainer = RuntimeTests.GetUmbracoContainer(out var serviceProviderFactory);
|
||||
|
||||
IHostApplicationLifetime lifetime1 = null;
|
||||
|
||||
var hostBuilder = new HostBuilder()
|
||||
.UseUmbraco(serviceProviderFactory)
|
||||
.ConfigureServices((hostContext, services) =>
|
||||
{
|
||||
// Resolve a service from the netcore container before the host has finished the ConfigureServices sequence
|
||||
lifetime1 = services.BuildServiceProvider().GetRequiredService<IHostApplicationLifetime>();
|
||||
|
||||
// Re-add as a callback, ensures its the same instance all the way through (hack)
|
||||
services.AddSingleton<IHostApplicationLifetime>(x => lifetime1);
|
||||
});
|
||||
|
||||
var host = await hostBuilder.StartAsync();
|
||||
|
||||
var lifetime2 = host.Services.GetRequiredService<IHostApplicationLifetime>();
|
||||
var lifetime3 = umbracoContainer.GetInstance<IHostApplicationLifetime>();
|
||||
|
||||
lifetime1.StopApplication();
|
||||
Assert.IsTrue(lifetime1.ApplicationStopping.IsCancellationRequested);
|
||||
Assert.AreEqual(lifetime1.ApplicationStopping.IsCancellationRequested, lifetime2.ApplicationStopping.IsCancellationRequested);
|
||||
Assert.AreEqual(lifetime1.ApplicationStopping.IsCancellationRequested, lifetime3.ApplicationStopping.IsCancellationRequested);
|
||||
|
||||
}
|
||||
|
||||
private class Foo
|
||||
{
|
||||
public Foo()
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Data.SqlClient;
|
||||
using System.IO;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Tests.Integration.Testing;
|
||||
|
||||
namespace Umbraco.Tests.Integration.Implementations
|
||||
{
|
||||
public static class HostBuilderExtensions
|
||||
{
|
||||
|
||||
public static IHostBuilder UseLocalDb(this IHostBuilder hostBuilder, string dbFilePath)
|
||||
{
|
||||
// Need to register SqlClient manually
|
||||
// TODO: Move this to someplace central
|
||||
DbProviderFactories.RegisterFactory(Constants.DbProviderNames.SqlServer, SqlClientFactory.Instance);
|
||||
|
||||
hostBuilder.ConfigureAppConfiguration(x =>
|
||||
{
|
||||
if (!Directory.Exists(dbFilePath))
|
||||
Directory.CreateDirectory(dbFilePath);
|
||||
|
||||
var dbName = Guid.NewGuid().ToString("N");
|
||||
var instance = TestLocalDb.EnsureLocalDbInstanceAndDatabase(dbName, dbFilePath);
|
||||
|
||||
x.AddInMemoryCollection(new[]
|
||||
{
|
||||
new KeyValuePair<string, string>($"ConnectionStrings:{Constants.System.UmbracoConnectionName}", instance.GetConnectionString(dbName))
|
||||
});
|
||||
});
|
||||
return hostBuilder;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
using System.Data.Common;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Tests.Integration.Implementations
|
||||
{
|
||||
public class TestDbProviderFactoryCreator : IDbProviderFactoryCreator
|
||||
{
|
||||
public IBulkSqlInsertProvider CreateBulkSqlInsertProvider(string providerName)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void CreateDatabase()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public DbProviderFactory CreateFactory()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public DbProviderFactory CreateFactory(string providerName)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public ISqlSyntaxProvider GetSqlSyntaxProvider(string providerName)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,14 +3,16 @@ using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Moq;
|
||||
using System.Data.Common;
|
||||
using System.Net;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Diagnostics;
|
||||
using Umbraco.Core.Hosting;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.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;
|
||||
@@ -18,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 IApplicationShutdownRegistry _hostingLifetime;
|
||||
private readonly IIpResolver _ipResolver;
|
||||
private readonly IWebHostEnvironment _hostEnvironment;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
@@ -39,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<IHostApplicationLifetime>());
|
||||
_httpContextAccessor);
|
||||
|
||||
_hostingLifetime = new AspNetCoreApplicationShutdownRegistry(Mock.Of<IHostApplicationLifetime>());
|
||||
|
||||
Logger = new ProfilingLogger(new ConsoleLogger(new MessageTemplates()), Profiler);
|
||||
}
|
||||
@@ -60,7 +63,7 @@ namespace Umbraco.Tests.Integration.Implementations
|
||||
|
||||
public IWebHostEnvironment GetWebHostEnvironment() => _hostEnvironment;
|
||||
|
||||
public override IDbProviderFactoryCreator DbProviderFactoryCreator => new TestDbProviderFactoryCreator();
|
||||
public override IDbProviderFactoryCreator DbProviderFactoryCreator => new SqlServerDbProviderFactoryCreator(Constants.DbProviderNames.SqlServer, DbProviderFactories.GetFactory);
|
||||
|
||||
public override IBulkSqlInsertProvider BulkSqlInsertProvider => new SqlServerBulkSqlInsertProvider();
|
||||
|
||||
@@ -74,7 +77,9 @@ namespace Umbraco.Tests.Integration.Implementations
|
||||
}
|
||||
|
||||
public override IHostingEnvironment GetHostingEnvironment() => _hostingEnvironment;
|
||||
public override IApplicationShutdownRegistry GetHostingEnvironmentLifetime() => _hostingLifetime;
|
||||
|
||||
public override IIpResolver GetIpResolver() => _ipResolver;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override for tests since we are not hosted
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 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.
|
||||
/// </remarks>
|
||||
bool Umbraco.Core.Hosting.IHostingEnvironment.IsHosted { get; } = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace Umbraco.Tests.Integration.Implementations
|
||||
{
|
||||
/// <summary>
|
||||
/// Ensures the host lifetime ends as soon as code execution is done
|
||||
/// </summary>
|
||||
public class TestLifetime : IHostLifetime
|
||||
{
|
||||
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
|
||||
|
||||
public Task WaitForStartAsync(CancellationToken cancellationToken) => Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -7,41 +7,76 @@ using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Moq;
|
||||
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;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Migrations.Install;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Runtime;
|
||||
using Umbraco.Tests.Common;
|
||||
using Umbraco.Tests.Integration.Implementations;
|
||||
using Umbraco.Tests.Integration.Testing;
|
||||
using Umbraco.Web.BackOffice.AspNetCore;
|
||||
using static Umbraco.Core.Migrations.Install.DatabaseBuilder;
|
||||
|
||||
namespace Umbraco.Tests.Integration
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class RuntimeTests
|
||||
{
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
MyComponent.Reset();
|
||||
MyComposer.Reset();
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void FixtureTearDown()
|
||||
{
|
||||
TestLocalDb.Cleanup();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manually configure the containers/dependencies and call Boot on Core runtime
|
||||
/// </summary>
|
||||
[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<IHostApplicationLifetime>());
|
||||
|
||||
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);
|
||||
|
||||
@@ -52,40 +87,150 @@ namespace Umbraco.Tests.Integration
|
||||
Assert.IsTrue(MyComponent.IsTerminated);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calling AddUmbracoCore to configure the container
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void AddUmbracoCore()
|
||||
public async Task AddUmbracoCore()
|
||||
{
|
||||
var umbracoContainer = GetUmbracoContainer(out var serviceProviderFactory);
|
||||
var testHelper = new TestHelper();
|
||||
|
||||
// MSDI
|
||||
var services = new ServiceCollection();
|
||||
// These services are required
|
||||
services.AddSingleton<IHttpContextAccessor>(x => testHelper.GetHttpContextAccessor());
|
||||
services.AddSingleton<IWebHostEnvironment>(x => testHelper.GetWebHostEnvironment());
|
||||
services.AddSingleton<IHostApplicationLifetime>(x => Mock.Of<IHostApplicationLifetime>());
|
||||
var hostBuilder = new HostBuilder()
|
||||
.UseUmbraco(serviceProviderFactory)
|
||||
.ConfigureServices((hostContext, services) =>
|
||||
{
|
||||
var webHostEnvironment = testHelper.GetWebHostEnvironment();
|
||||
AddRequiredNetCoreServices(services, testHelper, webHostEnvironment);
|
||||
|
||||
// LightInject / Umbraco
|
||||
var container = UmbracoServiceProviderFactory.CreateServiceContainer();
|
||||
var serviceProviderFactory = new UmbracoServiceProviderFactory(container);
|
||||
var umbracoContainer = serviceProviderFactory.GetContainer();
|
||||
// Add it!
|
||||
services.AddUmbracoConfiguration(hostContext.Configuration);
|
||||
services.AddUmbracoCore(webHostEnvironment, umbracoContainer, GetType().Assembly);
|
||||
});
|
||||
|
||||
// Some IConfiguration must exist in the container first
|
||||
var configurationBuilder = new ConfigurationBuilder();
|
||||
configurationBuilder.AddEnvironmentVariables();
|
||||
services.AddSingleton<IConfiguration>(x => configurationBuilder.Build());
|
||||
|
||||
// Add it!
|
||||
services.AddUmbracoConfiguration();
|
||||
services.AddUmbracoCore(umbracoContainer, GetType().Assembly);
|
||||
var host = await hostBuilder.StartAsync();
|
||||
var app = new ApplicationBuilder(host.Services);
|
||||
|
||||
// assert results
|
||||
var runtimeState = umbracoContainer.GetInstance<IRuntimeState>();
|
||||
var mainDom = umbracoContainer.GetInstance<IMainDom>();
|
||||
var runtimeState = app.ApplicationServices.GetRequiredService<IRuntimeState>();
|
||||
var mainDom = app.ApplicationServices.GetRequiredService<IMainDom>();
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calling AddUmbracoCore to configure the container and UseUmbracoCore to start the runtime
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Test]
|
||||
public async Task UseUmbracoCore()
|
||||
{
|
||||
var umbracoContainer = GetUmbracoContainer(out var serviceProviderFactory);
|
||||
var testHelper = new TestHelper();
|
||||
|
||||
var hostBuilder = new HostBuilder()
|
||||
.UseUmbraco(serviceProviderFactory)
|
||||
.ConfigureServices((hostContext, services) =>
|
||||
{
|
||||
var webHostEnvironment = testHelper.GetWebHostEnvironment();
|
||||
AddRequiredNetCoreServices(services, testHelper, webHostEnvironment);
|
||||
|
||||
// Add it!
|
||||
services.AddUmbracoConfiguration(hostContext.Configuration);
|
||||
services.AddUmbracoCore(webHostEnvironment, umbracoContainer, GetType().Assembly);
|
||||
});
|
||||
|
||||
var host = await hostBuilder.StartAsync();
|
||||
var app = new ApplicationBuilder(host.Services);
|
||||
|
||||
app.UseUmbracoCore();
|
||||
|
||||
|
||||
// assert results
|
||||
var runtimeState = app.ApplicationServices.GetRequiredService<IRuntimeState>();
|
||||
var mainDom = app.ApplicationServices.GetRequiredService<IMainDom>();
|
||||
|
||||
Assert.IsTrue(mainDom.IsMainDom);
|
||||
Assert.IsNull(runtimeState.BootFailedException);
|
||||
Assert.AreEqual(RuntimeLevel.Install, runtimeState.Level);
|
||||
Assert.IsTrue(MyComposer.IsComposed);
|
||||
Assert.IsTrue(MyComponent.IsInit);
|
||||
|
||||
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) =>
|
||||
{
|
||||
var webHostEnvironment = testHelper.GetWebHostEnvironment();
|
||||
AddRequiredNetCoreServices(services, testHelper, webHostEnvironment);
|
||||
|
||||
// Add it!
|
||||
services.AddUmbracoConfiguration(hostContext.Configuration);
|
||||
services.AddUmbracoCore(webHostEnvironment, umbracoContainer, GetType().Assembly);
|
||||
});
|
||||
|
||||
var host = await hostBuilder.StartAsync();
|
||||
var app = new ApplicationBuilder(host.Services);
|
||||
|
||||
app.UseUmbracoCore();
|
||||
|
||||
|
||||
var runtimeState = (RuntimeState)app.ApplicationServices.GetRequiredService<IRuntimeState>();
|
||||
Assert.AreEqual(RuntimeLevel.Install, runtimeState.Level);
|
||||
|
||||
var dbBuilder = app.ApplicationServices.GetRequiredService<DatabaseBuilder>();
|
||||
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<IUmbracoDatabaseFactory>();
|
||||
//var profilingLogger = app.ApplicationServices.GetRequiredService<IProfilingLogger>();
|
||||
//runtimeState.DetermineRuntimeLevel(dbFactory, profilingLogger);
|
||||
//Assert.AreEqual(RuntimeLevel.Run, runtimeState.Level);
|
||||
}
|
||||
|
||||
internal static LightInjectContainer GetUmbracoContainer(out UmbracoServiceProviderFactory serviceProviderFactory)
|
||||
{
|
||||
var container = UmbracoServiceProviderFactory.CreateServiceContainer();
|
||||
serviceProviderFactory = new UmbracoServiceProviderFactory(container);
|
||||
var umbracoContainer = serviceProviderFactory.GetContainer();
|
||||
return umbracoContainer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// These services need to be manually added because they do not get added by the generic host
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="testHelper"></param>
|
||||
/// <param name="webHostEnvironment"></param>
|
||||
private void AddRequiredNetCoreServices(IServiceCollection services, TestHelper testHelper, IWebHostEnvironment webHostEnvironment)
|
||||
{
|
||||
services.AddSingleton<IHttpContextAccessor>(x => testHelper.GetHttpContextAccessor());
|
||||
// the generic host does add IHostEnvironment but not this one because we are not actually in a web context
|
||||
services.AddSingleton<IWebHostEnvironment>(x => webHostEnvironment);
|
||||
}
|
||||
|
||||
[RuntimeLevel(MinLevel = RuntimeLevel.Install)]
|
||||
@@ -97,6 +242,11 @@ namespace Umbraco.Tests.Integration
|
||||
IsComposed = true;
|
||||
}
|
||||
|
||||
public static void Reset()
|
||||
{
|
||||
IsComposed = false;
|
||||
}
|
||||
|
||||
public static bool IsComposed { get; private set; }
|
||||
}
|
||||
|
||||
@@ -121,6 +271,12 @@ namespace Umbraco.Tests.Integration
|
||||
{
|
||||
IsTerminated = true;
|
||||
}
|
||||
|
||||
public static void Reset()
|
||||
{
|
||||
IsTerminated = false;
|
||||
IsInit = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Umbraco.Core.Persistence;
|
||||
|
||||
namespace Umbraco.Tests.Integration.Testing
|
||||
{
|
||||
public static class TestLocalDb
|
||||
{
|
||||
private const string LocalDbInstanceName = "UmbTests";
|
||||
|
||||
private static LocalDb LocalDb { get; } = new LocalDb();
|
||||
|
||||
// TODO: We need to borrow logic from this old branch, this is the latest commit at the old branch where we had LocalDb
|
||||
// working for tests. There's a lot of hoops to jump through to make it work 'fast'. Turns out it didn't actually run as
|
||||
// fast as SqlCe due to the dropping/creating of DB instances since that is faster in SqlCe but this code was all heavily
|
||||
// optimized to go as fast as possible.
|
||||
// see https://github.com/umbraco/Umbraco-CMS/blob/3a8716ac7b1c48b51258724337086cd0712625a1/src/Umbraco.Tests/TestHelpers/LocalDbTestDatabase.cs
|
||||
internal static LocalDb.Instance EnsureLocalDbInstanceAndDatabase(string dbName, string dbFilePath)
|
||||
{
|
||||
if (!LocalDb.InstanceExists(LocalDbInstanceName) && !LocalDb.CreateInstance(LocalDbInstanceName))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Failed to create LocalDb instance {LocalDbInstanceName}, assuming LocalDb is not really available.");
|
||||
}
|
||||
|
||||
var instance = LocalDb.GetInstance(LocalDbInstanceName);
|
||||
|
||||
if (instance == null)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Failed to get LocalDb instance {LocalDbInstanceName}, assuming LocalDb is not really available.");
|
||||
}
|
||||
|
||||
instance.CreateDatabase(dbName, dbFilePath);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static void Cleanup()
|
||||
{
|
||||
var instance = LocalDb.GetInstance(LocalDbInstanceName);
|
||||
if (instance != null)
|
||||
{
|
||||
instance.DropDatabases();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Data.SqlClient" Version="4.8.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="obj\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Remove="obj\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="obj\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Umbraco.Abstractions\Umbraco.Abstractions.csproj" />
|
||||
<ProjectReference Include="..\Umbraco.Configuration\Umbraco.Configuration.csproj" />
|
||||
<ProjectReference Include="..\Umbraco.Infrastructure\Umbraco.Infrastructure.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Faker.Net" Version="1.1.1" />
|
||||
<PackageReference Include="Moq" Version="4.13.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,39 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Configuration.Models;
|
||||
using Umbraco.Core;
|
||||
|
||||
namespace Umbraco.Tests.UnitTests.Umbraco.Configuration.Models
|
||||
{
|
||||
public class ConnectionStringsTests
|
||||
{
|
||||
[Test]
|
||||
[TestCase("", ExpectedResult = null)]
|
||||
[TestCase(null, ExpectedResult = null)]
|
||||
[TestCase(@"Data Source=|DataDirectory|\Umbraco.sdf;Flush Interval=1;", ExpectedResult = Constants.DbProviderNames.SqlCe)]
|
||||
[TestCase(@"Server=(LocalDb)\Umbraco;Database=NetCore;Integrated Security=true", ExpectedResult = Constants.DbProviderNames.SqlServer)]
|
||||
public string ParseProviderName(string connectionString)
|
||||
{
|
||||
var key = Constants.System.UmbracoConnectionName;
|
||||
var configuration = new Mock<IConfiguration>();
|
||||
|
||||
|
||||
//This is the underlying method that is called by Configuration.GetConnectionString(string)
|
||||
if (connectionString != null)
|
||||
{
|
||||
configuration.Setup(x => x.GetSection("ConnectionStrings")[key]).Returns(connectionString);
|
||||
}
|
||||
|
||||
|
||||
var connectionStrings = new ConnectionStrings(configuration.Object);
|
||||
|
||||
var actual = connectionStrings[key];
|
||||
|
||||
Assert.AreEqual(connectionString, actual.ConnectionString);
|
||||
Assert.AreEqual(key, actual.Name);
|
||||
|
||||
return connectionStrings[key].ProviderName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Tests.Common.Builders;
|
||||
using Umbraco.Tests.Common.Builders.Extensions;
|
||||
|
||||
|
||||
namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Models
|
||||
{
|
||||
[TestFixture]
|
||||
public class DataTypeTests
|
||||
{
|
||||
|
||||
private readonly DataTypeBuilder _builder = new DataTypeBuilder();
|
||||
[Test]
|
||||
public void Can_Deep_Clone()
|
||||
{
|
||||
var dtd = _builder
|
||||
.WithId(3123)
|
||||
.Build();
|
||||
|
||||
var clone = (DataType) dtd.DeepClone();
|
||||
|
||||
Assert.AreNotSame(clone, dtd);
|
||||
Assert.AreEqual(clone, dtd);
|
||||
Assert.AreEqual(clone.CreateDate, dtd.CreateDate);
|
||||
Assert.AreEqual(clone.CreatorId, dtd.CreatorId);
|
||||
Assert.AreEqual(clone.DatabaseType, dtd.DatabaseType);
|
||||
Assert.AreEqual(clone.Id, dtd.Id);
|
||||
Assert.AreEqual(clone.Key, dtd.Key);
|
||||
Assert.AreEqual(clone.Level, dtd.Level);
|
||||
Assert.AreEqual(clone.Name, dtd.Name);
|
||||
Assert.AreEqual(clone.ParentId, dtd.ParentId);
|
||||
Assert.AreEqual(clone.Path, dtd.Path);
|
||||
Assert.AreEqual(clone.SortOrder, dtd.SortOrder);
|
||||
Assert.AreEqual(clone.Trashed, dtd.Trashed);
|
||||
Assert.AreEqual(clone.UpdateDate, dtd.UpdateDate);
|
||||
|
||||
//This double verifies by reflection
|
||||
var allProps = clone.GetType().GetProperties();
|
||||
foreach (var propertyInfo in allProps)
|
||||
{
|
||||
Assert.AreEqual(propertyInfo.GetValue(clone, null), propertyInfo.GetValue(dtd, null));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Serialize_Without_Error()
|
||||
{
|
||||
var item = _builder.Build();
|
||||
|
||||
Assert.DoesNotThrow(() => JsonConvert.SerializeObject(item));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Tests.Common.Builders;
|
||||
|
||||
namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Models
|
||||
{
|
||||
[TestFixture]
|
||||
public class DictionaryItemTests
|
||||
{
|
||||
private readonly DictionaryItemBuilder _builder = new DictionaryItemBuilder();
|
||||
|
||||
[Test]
|
||||
public void Can_Deep_Clone()
|
||||
{
|
||||
var item = _builder
|
||||
.WithRandomTranslations(2)
|
||||
.Build();
|
||||
|
||||
var clone = (DictionaryItem)item.DeepClone();
|
||||
|
||||
Assert.AreNotSame(clone, item);
|
||||
Assert.AreEqual(clone, item);
|
||||
Assert.AreEqual(clone.CreateDate, item.CreateDate);
|
||||
Assert.AreEqual(clone.Id, item.Id);
|
||||
Assert.AreEqual(clone.ItemKey, item.ItemKey);
|
||||
Assert.AreEqual(clone.Key, item.Key);
|
||||
Assert.AreEqual(clone.ParentId, item.ParentId);
|
||||
Assert.AreEqual(clone.UpdateDate, item.UpdateDate);
|
||||
Assert.AreEqual(clone.Translations.Count(), item.Translations.Count());
|
||||
for (var i = 0; i < item.Translations.Count(); i++)
|
||||
{
|
||||
Assert.AreNotSame(clone.Translations.ElementAt(i), item.Translations.ElementAt(i));
|
||||
Assert.AreEqual(clone.Translations.ElementAt(i), item.Translations.ElementAt(i));
|
||||
}
|
||||
|
||||
//This double verifies by reflection
|
||||
var allProps = clone.GetType().GetProperties();
|
||||
foreach (var propertyInfo in allProps)
|
||||
{
|
||||
Assert.AreEqual(propertyInfo.GetValue(clone, null), propertyInfo.GetValue(item, null));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Serialize_Without_Error()
|
||||
{
|
||||
var item = _builder
|
||||
.WithRandomTranslations(2)
|
||||
.Build();
|
||||
|
||||
Assert.DoesNotThrow(() => JsonConvert.SerializeObject(item));
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
-29
@@ -1,32 +1,19 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Serialization;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Tests.Common.Builders;
|
||||
|
||||
namespace Umbraco.Tests.Models
|
||||
namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Models
|
||||
{
|
||||
[TestFixture]
|
||||
public class LanguageTests
|
||||
{
|
||||
private IGlobalSettings GlobalSettings { get; } = SettingsForTests.GenerateMockGlobalSettings();
|
||||
private readonly LanguageBuilder _builder = new LanguageBuilder();
|
||||
|
||||
[Test]
|
||||
public void Can_Deep_Clone()
|
||||
{
|
||||
var item = new Language(GlobalSettings, "en-AU")
|
||||
{
|
||||
CreateDate = DateTime.Now,
|
||||
CultureName = "AU",
|
||||
Id = 11,
|
||||
IsoCode = "en",
|
||||
Key = Guid.NewGuid(),
|
||||
UpdateDate = DateTime.Now
|
||||
};
|
||||
var item = _builder.Build();
|
||||
|
||||
var clone = (Language) item.DeepClone();
|
||||
Assert.AreNotSame(clone, item);
|
||||
@@ -49,18 +36,9 @@ namespace Umbraco.Tests.Models
|
||||
[Test]
|
||||
public void Can_Serialize_Without_Error()
|
||||
{
|
||||
var item = new Language(GlobalSettings, "en-AU")
|
||||
{
|
||||
CreateDate = DateTime.Now,
|
||||
CultureName = "AU",
|
||||
Id = 11,
|
||||
IsoCode = "en",
|
||||
Key = Guid.NewGuid(),
|
||||
UpdateDate = DateTime.Now
|
||||
};
|
||||
var item = _builder.Build();
|
||||
|
||||
var json = JsonConvert.SerializeObject(item);
|
||||
Debug.Print(json);
|
||||
Assert.DoesNotThrow(() => JsonConvert.SerializeObject(item));
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
-24
@@ -1,39 +1,37 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Serialization;
|
||||
using Umbraco.Tests.Common.Builders;
|
||||
|
||||
namespace Umbraco.Tests.Models
|
||||
namespace Umbraco.Tests.UnitTests.Umbraco.Infrastructure.Models
|
||||
{
|
||||
[TestFixture]
|
||||
public class RelationTypeTests
|
||||
{
|
||||
private readonly RelationTypeBuilder _builder = new RelationTypeBuilder();
|
||||
|
||||
[Test]
|
||||
public void Can_Deep_Clone()
|
||||
{
|
||||
var item = new RelationType("test", "test", false, Guid.NewGuid(), Guid.NewGuid())
|
||||
{
|
||||
Id = 66,
|
||||
CreateDate = DateTime.Now,
|
||||
IsBidirectional = true,
|
||||
Key = Guid.NewGuid(),
|
||||
Name = "Test",
|
||||
UpdateDate = DateTime.Now
|
||||
};
|
||||
var item = _builder
|
||||
.WithParentObjectType(Guid.NewGuid())
|
||||
.WithChildObjectType(Guid.NewGuid())
|
||||
.Build();
|
||||
|
||||
var clone = (RelationType)item.DeepClone();
|
||||
var clone = (RelationType) item.DeepClone();
|
||||
|
||||
Assert.AreNotSame(clone, item);
|
||||
Assert.AreEqual(clone, item);
|
||||
Assert.AreEqual(clone.Alias, item.Alias);
|
||||
Assert.AreEqual(clone.ChildObjectType, item.ChildObjectType);
|
||||
Assert.AreEqual(clone.ParentObjectType, item.ParentObjectType);
|
||||
Assert.AreEqual(clone.IsBidirectional, item.IsBidirectional);
|
||||
Assert.AreEqual(clone.Id, item.Id);
|
||||
Assert.AreEqual(clone.Key, item.Key);
|
||||
Assert.AreEqual(clone.Name, item.Name);
|
||||
Assert.AreNotSame(clone.ParentObjectType, item.ParentObjectType);
|
||||
Assert.AreNotSame(clone.ChildObjectType, item.ChildObjectType);
|
||||
Assert.AreEqual(clone.UpdateDate, item.UpdateDate);
|
||||
|
||||
//This double verifies by reflection
|
||||
@@ -47,18 +45,9 @@ namespace Umbraco.Tests.Models
|
||||
[Test]
|
||||
public void Can_Serialize_Without_Error()
|
||||
{
|
||||
var item = new RelationType("test", "test", false, Guid.NewGuid(), Guid.NewGuid())
|
||||
{
|
||||
Id = 66,
|
||||
CreateDate = DateTime.Now,
|
||||
IsBidirectional = true,
|
||||
Key = Guid.NewGuid(),
|
||||
Name = "Test",
|
||||
UpdateDate = DateTime.Now
|
||||
};
|
||||
var item = _builder.Build();
|
||||
|
||||
var json = JsonConvert.SerializeObject(item);
|
||||
Debug.Print(json);
|
||||
Assert.DoesNotThrow(() => JsonConvert.SerializeObject(item));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="obj\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Remove="obj\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="obj\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Umbraco.Tests.Common\Umbraco.Tests.Common.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -41,6 +41,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
|
||||
private readonly IEntityXmlSerializer _entitySerializer;
|
||||
private readonly IVariationContextAccessor _variationContextAccessor;
|
||||
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
|
||||
private readonly IApplicationShutdownRegistry _hostingLifetime;
|
||||
private readonly IHostingEnvironment _hostingEnvironment;
|
||||
|
||||
#region Constructors
|
||||
@@ -57,6 +58,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
|
||||
ILogger logger,
|
||||
IGlobalSettings globalSettings,
|
||||
IHostingEnvironment hostingEnvironment,
|
||||
IApplicationShutdownRegistry 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,
|
||||
IApplicationShutdownRegistry 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()
|
||||
|
||||
@@ -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 IApplicationShutdownRegistry _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
|
||||
/// </summary>
|
||||
/// <remarks>The default constructor will boot the cache, load data from file or database, /// wire events in order to manage changes, etc.</remarks>
|
||||
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, IApplicationShutdownRegistry 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, IApplicationShutdownRegistry 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()
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Serialization;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Strings;
|
||||
|
||||
namespace Umbraco.Tests.Models
|
||||
{
|
||||
[TestFixture]
|
||||
public class DataTypeTests
|
||||
{
|
||||
[Test]
|
||||
public void Can_Deep_Clone()
|
||||
{
|
||||
var dtd = new DataType(new VoidEditor(Mock.Of<ILogger>(), Mock.Of<IDataTypeService>(), Mock.Of<ILocalizationService>(),Mock.Of<ILocalizedTextService>(), Mock.Of<IShortStringHelper>()), 9)
|
||||
{
|
||||
CreateDate = DateTime.Now,
|
||||
CreatorId = 5,
|
||||
DatabaseType = ValueStorageType.Nvarchar,
|
||||
Id = 4,
|
||||
Key = Guid.NewGuid(),
|
||||
Level = 7,
|
||||
Name = "Test",
|
||||
ParentId = 9,
|
||||
Path = "-1,2",
|
||||
SortOrder = 8,
|
||||
Trashed = true,
|
||||
UpdateDate = DateTime.Now
|
||||
};
|
||||
var clone = (DataType) dtd.DeepClone();
|
||||
|
||||
Assert.AreNotSame(clone, dtd);
|
||||
Assert.AreEqual(clone, dtd);
|
||||
Assert.AreEqual(clone.CreateDate, dtd.CreateDate);
|
||||
Assert.AreEqual(clone.CreatorId, dtd.CreatorId);
|
||||
Assert.AreEqual(clone.DatabaseType, dtd.DatabaseType);
|
||||
Assert.AreEqual(clone.Id, dtd.Id);
|
||||
Assert.AreEqual(clone.Key, dtd.Key);
|
||||
Assert.AreEqual(clone.Level, dtd.Level);
|
||||
Assert.AreEqual(clone.Name, dtd.Name);
|
||||
Assert.AreEqual(clone.ParentId, dtd.ParentId);
|
||||
Assert.AreEqual(clone.Path, dtd.Path);
|
||||
Assert.AreEqual(clone.SortOrder, dtd.SortOrder);
|
||||
Assert.AreEqual(clone.Trashed, dtd.Trashed);
|
||||
Assert.AreEqual(clone.UpdateDate, dtd.UpdateDate);
|
||||
|
||||
//This double verifies by reflection
|
||||
var allProps = clone.GetType().GetProperties();
|
||||
foreach (var propertyInfo in allProps)
|
||||
{
|
||||
Assert.AreEqual(propertyInfo.GetValue(clone, null), propertyInfo.GetValue(dtd, null));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Serialize_Without_Error()
|
||||
{
|
||||
var dtd = new DataType(new VoidEditor(Mock.Of<ILogger>(), Mock.Of<IDataTypeService>(), Mock.Of<ILocalizationService>(), Mock.Of<ILocalizedTextService>(),Mock.Of<IShortStringHelper>()), 9)
|
||||
{
|
||||
CreateDate = DateTime.Now,
|
||||
CreatorId = 5,
|
||||
DatabaseType = ValueStorageType.Nvarchar,
|
||||
Id = 4,
|
||||
Key = Guid.NewGuid(),
|
||||
Level = 7,
|
||||
Name = "Test",
|
||||
ParentId = 9,
|
||||
Path = "-1,2",
|
||||
SortOrder = 8,
|
||||
Trashed = true,
|
||||
UpdateDate = DateTime.Now
|
||||
};
|
||||
|
||||
var json = JsonConvert.SerializeObject(dtd);
|
||||
Debug.Print(json);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Serialization;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
|
||||
namespace Umbraco.Tests.Models
|
||||
{
|
||||
[TestFixture]
|
||||
public class DictionaryItemTests
|
||||
{
|
||||
[Test]
|
||||
public void Can_Deep_Clone()
|
||||
{
|
||||
var item = new DictionaryItem("blah")
|
||||
{
|
||||
CreateDate = DateTime.Now,
|
||||
Id = 8,
|
||||
ItemKey = "blah",
|
||||
Key = Guid.NewGuid(),
|
||||
ParentId = Guid.NewGuid(),
|
||||
UpdateDate = DateTime.Now,
|
||||
Translations = new[]
|
||||
{
|
||||
new DictionaryTranslation(new Language(SettingsForTests.GenerateMockGlobalSettings(),"en-AU")
|
||||
{
|
||||
CreateDate = DateTime.Now,
|
||||
CultureName = "en",
|
||||
Id = 11,
|
||||
IsoCode = "AU",
|
||||
Key = Guid.NewGuid(),
|
||||
UpdateDate = DateTime.Now
|
||||
}, "colour")
|
||||
{
|
||||
CreateDate = DateTime.Now,
|
||||
Id = 88,
|
||||
Key = Guid.NewGuid(),
|
||||
UpdateDate = DateTime.Now
|
||||
},
|
||||
new DictionaryTranslation(new Language(SettingsForTests.GenerateMockGlobalSettings(),"en-US")
|
||||
{
|
||||
CreateDate = DateTime.Now,
|
||||
CultureName = "en",
|
||||
Id = 12,
|
||||
IsoCode = "US",
|
||||
Key = Guid.NewGuid(),
|
||||
UpdateDate = DateTime.Now
|
||||
}, "color")
|
||||
{
|
||||
CreateDate = DateTime.Now,
|
||||
Id = 89,
|
||||
Key = Guid.NewGuid(),
|
||||
UpdateDate = DateTime.Now
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
var clone = (DictionaryItem)item.DeepClone();
|
||||
|
||||
Assert.AreNotSame(clone, item);
|
||||
Assert.AreEqual(clone, item);
|
||||
Assert.AreEqual(clone.CreateDate, item.CreateDate);
|
||||
Assert.AreEqual(clone.Id, item.Id);
|
||||
Assert.AreEqual(clone.ItemKey, item.ItemKey);
|
||||
Assert.AreEqual(clone.Key, item.Key);
|
||||
Assert.AreEqual(clone.ParentId, item.ParentId);
|
||||
Assert.AreEqual(clone.UpdateDate, item.UpdateDate);
|
||||
Assert.AreEqual(clone.Translations.Count(), item.Translations.Count());
|
||||
for (var i = 0; i < item.Translations.Count(); i++)
|
||||
{
|
||||
Assert.AreNotSame(clone.Translations.ElementAt(i), item.Translations.ElementAt(i));
|
||||
Assert.AreEqual(clone.Translations.ElementAt(i), item.Translations.ElementAt(i));
|
||||
}
|
||||
|
||||
//This double verifies by reflection
|
||||
var allProps = clone.GetType().GetProperties();
|
||||
foreach (var propertyInfo in allProps)
|
||||
{
|
||||
Assert.AreEqual(propertyInfo.GetValue(clone, null), propertyInfo.GetValue(item, null));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Serialize_Without_Error()
|
||||
{
|
||||
var item = new DictionaryItem("blah")
|
||||
{
|
||||
CreateDate = DateTime.Now,
|
||||
Id = 8,
|
||||
ItemKey = "blah",
|
||||
Key = Guid.NewGuid(),
|
||||
ParentId = Guid.NewGuid(),
|
||||
UpdateDate = DateTime.Now,
|
||||
Translations = new[]
|
||||
{
|
||||
new DictionaryTranslation(new Language(SettingsForTests.GenerateMockGlobalSettings(),"en-AU")
|
||||
{
|
||||
CreateDate = DateTime.Now,
|
||||
CultureName = "en",
|
||||
Id = 11,
|
||||
IsoCode = "AU",
|
||||
Key = Guid.NewGuid(),
|
||||
UpdateDate = DateTime.Now
|
||||
}, "colour")
|
||||
{
|
||||
CreateDate = DateTime.Now,
|
||||
Id = 88,
|
||||
Key = Guid.NewGuid(),
|
||||
UpdateDate = DateTime.Now
|
||||
},
|
||||
new DictionaryTranslation(new Language(SettingsForTests.GenerateMockGlobalSettings(),"en-US")
|
||||
{
|
||||
CreateDate = DateTime.Now,
|
||||
CultureName = "en",
|
||||
Id = 12,
|
||||
IsoCode = "US",
|
||||
Key = Guid.NewGuid(),
|
||||
UpdateDate = DateTime.Now
|
||||
}, "color")
|
||||
{
|
||||
CreateDate = DateTime.Now,
|
||||
Id = 89,
|
||||
Key = Guid.NewGuid(),
|
||||
UpdateDate = DateTime.Now
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var json = JsonConvert.SerializeObject(item);
|
||||
Debug.Print(json);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,8 +32,7 @@ namespace Umbraco.Tests.Routing
|
||||
//create the module
|
||||
var logger = Mock.Of<ILogger>();
|
||||
var globalSettings = TestObjects.GetGlobalSettings();
|
||||
var runtime = new RuntimeState(logger, globalSettings,
|
||||
new Lazy<IMainDom>(), new Lazy<IServerRegistrar>(), UmbracoVersion, HostingEnvironment, BackOfficeInfo);
|
||||
var runtime = new RuntimeState(logger, globalSettings, UmbracoVersion, BackOfficeInfo);
|
||||
|
||||
_module = new UmbracoInjectedModule
|
||||
(
|
||||
|
||||
@@ -104,11 +104,6 @@ namespace Umbraco.Tests.Runtimes
|
||||
return configs;
|
||||
}
|
||||
|
||||
private static IProfiler GetProfiler()
|
||||
{
|
||||
return new TestProfiler();
|
||||
}
|
||||
|
||||
public IRuntime Runtime { get; private set; }
|
||||
|
||||
protected override IRuntime GetRuntime(Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger, IProfiler profiler, IHostingEnvironment hostingEnvironment, IBackOfficeInfo backOfficeInfo)
|
||||
@@ -136,50 +131,14 @@ namespace Umbraco.Tests.Runtimes
|
||||
return mock.Object;
|
||||
}
|
||||
|
||||
// FIXME: so how the f* should we do it now?
|
||||
/*
|
||||
// pretend we have the proper migration
|
||||
// else BootFailedException because our mock IUmbracoDatabaseFactory does not provide databases
|
||||
protected override bool EnsureUmbracoUpgradeState(IUmbracoDatabaseFactory databaseFactory)
|
||||
public override IFactory Configure(IRegister container)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
container.Register<IApplicationShutdownRegistry, AspNetApplicationShutdownRegistry>(Lifetime.Singleton);
|
||||
|
||||
// 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<IScopeProvider>();
|
||||
Mock.Get(scopeProvider)
|
||||
.Setup(x => x.CreateScope(
|
||||
It.IsAny<IsolationLevel>(),
|
||||
It.IsAny<RepositoryCacheMode>(),
|
||||
It.IsAny<IEventDispatcher>(),
|
||||
It.IsAny<bool?>(),
|
||||
It.IsAny<bool>(),
|
||||
It.IsAny<bool>()))
|
||||
.Returns(Mock.Of<IScope>());
|
||||
|
||||
composition.RegisterUnique(scopeProvider);
|
||||
}
|
||||
|
||||
private IMainDom _mainDom;
|
||||
|
||||
public override IFactory Boot(IRegister container)
|
||||
{
|
||||
var factory = base.Boot(container);
|
||||
_mainDom = factory.GetInstance<IMainDom>();
|
||||
var factory = base.Configure(container);
|
||||
return factory;
|
||||
}
|
||||
|
||||
public override void Terminate()
|
||||
{
|
||||
base.Terminate();
|
||||
}
|
||||
|
||||
// runs with only one single component
|
||||
// UmbracoCoreComponent will be force-added too
|
||||
// and that's it
|
||||
|
||||
@@ -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<IMainDom>(() => mainDom), new Lazy<IServerRegistrar>(() => factory.GetInstance<IServerRegistrar>()), umbracoVersion, hostingEnvironment, backOfficeInfo);
|
||||
var runtimeState = new RuntimeState(logger, null, umbracoVersion, backOfficeInfo);
|
||||
var configs = TestHelper.GetConfigs();
|
||||
var variationContextAccessor = TestHelper.VariationContextAccessor;
|
||||
|
||||
@@ -80,11 +80,10 @@ namespace Umbraco.Tests.Runtimes
|
||||
// create the register and the composition
|
||||
var register = TestHelper.GetRegister();
|
||||
var composition = new Composition(register, typeLoader, profilingLogger, runtimeState, configs, ioHelper, appCaches);
|
||||
composition.RegisterEssentials(logger, profiler, profilingLogger, mainDom, appCaches, databaseFactory, typeLoader, runtimeState, typeFinder, ioHelper, umbracoVersion, TestHelper.DbProviderFactoryCreator);
|
||||
composition.RegisterEssentials(logger, profiler, profilingLogger, mainDom, appCaches, databaseFactory, typeLoader, runtimeState, typeFinder, ioHelper, umbracoVersion, TestHelper.DbProviderFactoryCreator, hostingEnvironment, backOfficeInfo);
|
||||
|
||||
// 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);
|
||||
@@ -275,11 +274,10 @@ namespace Umbraco.Tests.Runtimes
|
||||
var register = TestHelper.GetRegister();
|
||||
var composition = new Composition(register, typeLoader, profilingLogger, runtimeState, configs, ioHelper, appCaches);
|
||||
var umbracoVersion = TestHelper.GetUmbracoVersion();
|
||||
composition.RegisterEssentials(logger, profiler, profilingLogger, mainDom, appCaches, databaseFactory, typeLoader, runtimeState, typeFinder, ioHelper, umbracoVersion, TestHelper.DbProviderFactoryCreator);
|
||||
composition.RegisterEssentials(logger, profiler, profilingLogger, mainDom, appCaches, databaseFactory, typeLoader, runtimeState, typeFinder, ioHelper, umbracoVersion, TestHelper.DbProviderFactoryCreator, hostingEnvironment, backOfficeInfo);
|
||||
|
||||
// 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?
|
||||
|
||||
@@ -19,13 +19,13 @@ namespace Umbraco.Tests.Scheduling
|
||||
public class BackgroundTaskRunnerTests
|
||||
{
|
||||
private ILogger _logger;
|
||||
private IHostingEnvironment _hostingEnvironment;
|
||||
private IApplicationShutdownRegistry _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<IBackgroundTask>(new BackgroundTaskRunnerOptions { KeepAlive = true, LongRunning = true }, _logger, TestHelper.GetHostingEnvironment());
|
||||
var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions { KeepAlive = true, LongRunning = true }, _logger, TestHelper.GetHostingEnvironmentLifetime());
|
||||
|
||||
var task = new SourceTask();
|
||||
runner.Add(task);
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Umbraco.Tests.Scheduling
|
||||
public async Task ThreadResumeIssue()
|
||||
{
|
||||
var logger = new DebugDiagnosticsLogger(new MessageTemplates());
|
||||
var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions { KeepAlive = true, LongRunning = true }, logger, TestHelper.GetHostingEnvironment());
|
||||
var runner = new BackgroundTaskRunner<IBackgroundTask>(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<IBackgroundTask>(new BackgroundTaskRunnerOptions { KeepAlive = true, LongRunning = true }, logger, TestHelper.GetHostingEnvironment());
|
||||
var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions { KeepAlive = true, LongRunning = true }, logger, TestHelper.GetHostingEnvironmentLifetime());
|
||||
var taskCompleted = false;
|
||||
runner.TaskCompleted += (sender, args) =>
|
||||
{
|
||||
|
||||
@@ -21,12 +21,12 @@ using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.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
|
||||
/// </summary>
|
||||
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 IApplicationShutdownRegistry GetHostingEnvironmentLifetime()
|
||||
=> new AspNetApplicationShutdownRegistry();
|
||||
|
||||
public override IIpResolver GetIpResolver()
|
||||
=> new AspNetIpResolver();
|
||||
}
|
||||
@@ -320,6 +323,8 @@ namespace Umbraco.Tests.TestHelpers
|
||||
|
||||
public static IHostingEnvironment GetHostingEnvironment() => _testHelperInternal.GetHostingEnvironment();
|
||||
|
||||
public static IApplicationShutdownRegistry GetHostingEnvironmentLifetime() => _testHelperInternal.GetHostingEnvironmentLifetime();
|
||||
|
||||
public static IIpResolver GetIpResolver() => _testHelperInternal.GetIpResolver();
|
||||
|
||||
public static IRequestCache GetRequestCache() => _testHelperInternal.GetRequestCache();
|
||||
|
||||
@@ -265,6 +265,7 @@ namespace Umbraco.Tests.TestHelpers
|
||||
Logger,
|
||||
Factory.GetInstance<IGlobalSettings>(),
|
||||
HostingEnvironment,
|
||||
HostingLifetime,
|
||||
ShortStringHelper,
|
||||
new SiteDomainHelper(),
|
||||
Factory.GetInstance<IEntityXmlSerializer>(),
|
||||
|
||||
@@ -51,10 +51,10 @@ using Umbraco.Web.Templates;
|
||||
using Umbraco.Web.PropertyEditors;
|
||||
using Umbraco.Core.Dictionary;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.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<IProfilingLogger>();
|
||||
|
||||
protected IHostingEnvironment HostingEnvironment { get; } = new AspNetHostingEnvironment(TestHelpers.SettingsForTests.GetDefaultHostingSettings());
|
||||
protected IApplicationShutdownRegistry HostingLifetime { get; } = new AspNetApplicationShutdownRegistry();
|
||||
protected IIpResolver IpResolver => Factory.GetInstance<IIpResolver>();
|
||||
protected IBackOfficeInfo BackOfficeInfo => Factory.GetInstance<IBackOfficeInfo>();
|
||||
protected AppCaches AppCaches => Factory.GetInstance<AppCaches>();
|
||||
|
||||
@@ -295,17 +295,13 @@
|
||||
<Compile Include="Models\Collections\OrderItem.cs" />
|
||||
<Compile Include="Models\Collections\SimpleOrder.cs" />
|
||||
<Compile Include="Models\ContentTypeTests.cs" />
|
||||
<Compile Include="Models\DataTypeTests.cs" />
|
||||
<Compile Include="Models\DeepCloneHelperTests.cs" />
|
||||
<Compile Include="Models\DictionaryItemTests.cs" />
|
||||
<Compile Include="Models\DictionaryTranslationTests.cs" />
|
||||
<Compile Include="Models\LanguageTests.cs" />
|
||||
<Compile Include="Models\MemberGroupTests.cs" />
|
||||
<Compile Include="Models\MemberTests.cs" />
|
||||
<Compile Include="Models\PropertyGroupTests.cs" />
|
||||
<Compile Include="Models\PropertyTypeTests.cs" />
|
||||
<Compile Include="Models\RelationTests.cs" />
|
||||
<Compile Include="Models\RelationTypeTests.cs" />
|
||||
<Compile Include="Models\TemplateTests.cs" />
|
||||
<Compile Include="Models\LightEntityTest.cs" />
|
||||
<Compile Include="Models\UserTests.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<IEntityXmlSerializer>(),
|
||||
|
||||
@@ -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 AspNetCoreApplicationShutdownRegistry : IApplicationShutdownRegistry
|
||||
{
|
||||
private readonly IHostApplicationLifetime _hostApplicationLifetime;
|
||||
private readonly ConcurrentDictionary<IRegisteredObject, RegisteredObjectWrapper> _registeredObjects =
|
||||
new ConcurrentDictionary<IRegisteredObject, RegisteredObjectWrapper>();
|
||||
|
||||
public AspNetCoreApplicationShutdownRegistry(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Hosting;
|
||||
using Umbraco.Net;
|
||||
using Umbraco.Core.Runtime;
|
||||
|
||||
namespace Umbraco.Web.BackOffice.AspNetCore
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds/replaces AspNetCore specific services
|
||||
/// </summary>
|
||||
[ComposeBefore(typeof(ICoreComposer))]
|
||||
[ComposeAfter(typeof(CoreInitialComposer))]
|
||||
public class AspNetCoreComposer : IComposer
|
||||
{
|
||||
public void Compose(Composition composition)
|
||||
{
|
||||
// AspNetCore specific services
|
||||
composition.RegisterUnique<IHttpContextAccessor, HttpContextAccessor>();
|
||||
|
||||
// Our own netcore implementations
|
||||
composition.RegisterUnique<IUmbracoApplicationLifetime, AspNetCoreUmbracoApplicationLifetime>();
|
||||
composition.RegisterUnique<IApplicationShutdownRegistry, AspNetCoreApplicationShutdownRegistry>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<IRegisteredObject, RegisteredObjectWrapper> _registeredObjects =
|
||||
new ConcurrentDictionary<IRegisteredObject, RegisteredObjectWrapper>();
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Umbraco.Core.Diagnostics;
|
||||
|
||||
namespace Umbraco.Web.BackOffice
|
||||
namespace Umbraco.Web.BackOffice.AspNetCore
|
||||
{
|
||||
|
||||
public class AspNetCoreMarchal : IMarchal
|
||||
|
||||
+54
-4
@@ -1,5 +1,10 @@
|
||||
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
|
||||
{
|
||||
@@ -7,12 +12,57 @@ namespace Umbraco.Web.BackOffice.AspNetCore
|
||||
{
|
||||
public static IApplicationBuilder UseUmbracoBackOffice(this IApplicationBuilder app)
|
||||
{
|
||||
if (app == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(app));
|
||||
}
|
||||
if (app == null) throw new ArgumentNullException(nameof(app));
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start Umbraco
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <returns></returns>
|
||||
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<IApplicationShutdownRegistry>();
|
||||
var runtime = app.ApplicationServices.GetRequiredService<IRuntime>();
|
||||
var runtimeShutdown = new CoreRuntimeShutdown(runtime, hostLifetime);
|
||||
hostLifetime.RegisterObject(runtimeShutdown);
|
||||
|
||||
// Start the runtime!
|
||||
runtime.Start();
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures the runtime is shutdown when the application is shutting down
|
||||
/// </summary>
|
||||
private class CoreRuntimeShutdown : IRegisteredObject
|
||||
{
|
||||
public CoreRuntimeShutdown(IRuntime runtime, IApplicationShutdownRegistry hostLifetime)
|
||||
{
|
||||
_runtime = runtime;
|
||||
_hostLifetime = hostLifetime;
|
||||
}
|
||||
|
||||
private bool _completed = false;
|
||||
private readonly IRuntime _runtime;
|
||||
private readonly IApplicationShutdownRegistry _hostLifetime;
|
||||
|
||||
public void Stop(bool immediate)
|
||||
{
|
||||
if (!_completed)
|
||||
{
|
||||
_completed = true;
|
||||
_runtime.Terminate();
|
||||
_hostLifetime.UnregisterObject(this);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+53
-41
@@ -12,7 +12,6 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Logging.Serilog;
|
||||
@@ -22,17 +21,18 @@ using Umbraco.Web.Common.Runtime.Profiler;
|
||||
|
||||
namespace Umbraco.Web.BackOffice.AspNetCore
|
||||
{
|
||||
|
||||
|
||||
public static class UmbracoBackOfficeServiceCollectionExtensions
|
||||
// TODO: Move to Umbraco.Web.Common
|
||||
public static class UmbracoCoreServiceCollectionExtensions
|
||||
{
|
||||
|
||||
public static IServiceCollection AddUmbracoConfiguration(this IServiceCollection services)
|
||||
/// <summary>
|
||||
/// Adds the Umbraco Configuration requirements
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="configuration"></param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddUmbracoConfiguration(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
var serviceProvider = services.BuildServiceProvider();
|
||||
var configuration = serviceProvider.GetService<IConfiguration>();
|
||||
if (configuration == null)
|
||||
throw new InvalidOperationException($"Could not resolve {typeof(IConfiguration)} from the container");
|
||||
if (configuration == null) throw new ArgumentNullException(nameof(configuration));
|
||||
|
||||
var configsFactory = new AspNetCoreConfigsFactory(configuration);
|
||||
|
||||
@@ -45,48 +45,59 @@ namespace Umbraco.Web.BackOffice.AspNetCore
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds the Umbraco Back Core requirements
|
||||
/// Adds the Umbraco Back Core requirements
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="webHostEnvironment"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// Must be called after all services are added to the application because we are cross-wiring the container (currently)
|
||||
/// </remarks>
|
||||
public static IServiceCollection AddUmbracoCore(this IServiceCollection services)
|
||||
public static IServiceCollection AddUmbracoCore(this IServiceCollection services, IWebHostEnvironment webHostEnvironment)
|
||||
{
|
||||
if (!UmbracoServiceProviderFactory.IsActive)
|
||||
throw new InvalidOperationException("Ensure to add UseUmbraco() in your Program.cs after ConfigureWebHostDefaults to enable Umbraco's service provider factory");
|
||||
|
||||
var umbContainer = UmbracoServiceProviderFactory.UmbracoContainer;
|
||||
|
||||
return services.AddUmbracoCore(umbContainer, Assembly.GetEntryAssembly());
|
||||
return services.AddUmbracoCore(webHostEnvironment, umbContainer, Assembly.GetEntryAssembly());
|
||||
}
|
||||
|
||||
public static IServiceCollection AddUmbracoCore(this IServiceCollection services, IRegister umbContainer, Assembly entryAssembly)
|
||||
/// <summary>
|
||||
/// Adds the Umbraco Back Core requirements
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="webHostEnvironment"></param>
|
||||
/// <param name="umbContainer"></param>
|
||||
/// <param name="entryAssembly"></param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddUmbracoCore(this IServiceCollection services, IWebHostEnvironment webHostEnvironment, IRegister umbContainer, Assembly entryAssembly)
|
||||
{
|
||||
if (services is null) throw new ArgumentNullException(nameof(services));
|
||||
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<IHttpContextAccessor, HttpContextAccessor>();
|
||||
|
||||
CreateCompositionRoot(services);
|
||||
CreateCompositionRoot(services, webHostEnvironment, 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 = Current.Configs.Global();
|
||||
var globalSettings = configs.Global();
|
||||
var umbracoVersion = new UmbracoVersion(globalSettings);
|
||||
|
||||
// TODO: Currently we are not passing in any TypeFinderConfig (with ITypeFinderSettings) which we should do, however
|
||||
// this is not critical right now and would require loading in some config before boot time so just leaving this as-is for now.
|
||||
var typeFinder = new TypeFinder(Current.Logger, new DefaultUmbracoAssemblyProvider(entryAssembly));
|
||||
var typeFinder = new TypeFinder(logger, new DefaultUmbracoAssemblyProvider(entryAssembly));
|
||||
|
||||
var coreRuntime = GetCoreRuntime(
|
||||
Current.Configs,
|
||||
configs,
|
||||
umbracoVersion,
|
||||
Current.IOHelper,
|
||||
Current.Logger,
|
||||
Current.Profiler,
|
||||
Current.HostingEnvironment,
|
||||
Current.BackOfficeInfo,
|
||||
ioHelper,
|
||||
logger,
|
||||
profiler,
|
||||
hostingEnvironment,
|
||||
backOfficeInfo,
|
||||
typeFinder);
|
||||
|
||||
var factory = coreRuntime.Boot(umbContainer);
|
||||
var factory = coreRuntime.Configure(umbContainer);
|
||||
|
||||
return services;
|
||||
}
|
||||
@@ -108,7 +119,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);
|
||||
@@ -116,17 +127,16 @@ namespace Umbraco.Web.BackOffice.AspNetCore
|
||||
return coreRuntime;
|
||||
}
|
||||
|
||||
private static void CreateCompositionRoot(IServiceCollection services)
|
||||
private static void CreateCompositionRoot(IServiceCollection services, IWebHostEnvironment webHostEnvironment,
|
||||
out ILogger logger, out Configs configs, out IIOHelper ioHelper, out Core.Hosting.IHostingEnvironment hostingEnvironment,
|
||||
out IBackOfficeInfo backOfficeInfo, out IProfiler profiler)
|
||||
{
|
||||
// TODO: This isn't the best to have to resolve the services now but to avoid this will
|
||||
// require quite a lot of re-work.
|
||||
// TODO: We need to avoid this, surely there's a way? See ContainerTests.BuildServiceProvider_Before_Host_Is_Configured
|
||||
var serviceProvider = services.BuildServiceProvider();
|
||||
|
||||
var httpContextAccessor = serviceProvider.GetRequiredService<IHttpContextAccessor>();
|
||||
var webHostEnvironment = serviceProvider.GetRequiredService<IWebHostEnvironment>();
|
||||
var hostApplicationLifetime = serviceProvider.GetRequiredService<IHostApplicationLifetime>();
|
||||
|
||||
var configs = serviceProvider.GetService<Configs>();
|
||||
configs = serviceProvider.GetService<Configs>();
|
||||
if (configs == null)
|
||||
throw new InvalidOperationException($"Could not resolve type {typeof(Configs)} from the container, ensure {nameof(AddUmbracoConfiguration)} is called before calling {nameof(AddUmbracoCore)}");
|
||||
|
||||
@@ -134,16 +144,16 @@ namespace Umbraco.Web.BackOffice.AspNetCore
|
||||
var coreDebug = configs.CoreDebug();
|
||||
var globalSettings = configs.Global();
|
||||
|
||||
var hostingEnvironment = new AspNetCoreHostingEnvironment(hostingSettings, webHostEnvironment, httpContextAccessor, hostApplicationLifetime);
|
||||
var ioHelper = new IOHelper(hostingEnvironment, globalSettings);
|
||||
var logger = SerilogLogger.CreateWithDefaultConfiguration(hostingEnvironment,
|
||||
hostingEnvironment = new AspNetCoreHostingEnvironment(hostingSettings, webHostEnvironment, httpContextAccessor);
|
||||
ioHelper = new IOHelper(hostingEnvironment, globalSettings);
|
||||
logger = SerilogLogger.CreateWithDefaultConfiguration(hostingEnvironment,
|
||||
new AspNetCoreSessionIdResolver(httpContextAccessor),
|
||||
// need to build a new service provider since the one already resolved above doesn't have the IRequestCache yet
|
||||
// TODO: We need to avoid this, surely there's a way? See ContainerTests.BuildServiceProvider_Before_Host_Is_Configured
|
||||
() => services.BuildServiceProvider().GetService<IRequestCache>(), coreDebug, ioHelper,
|
||||
new AspNetCoreMarchal());
|
||||
|
||||
var backOfficeInfo = new AspNetCoreBackOfficeInfo(globalSettings);
|
||||
var profiler = GetWebProfiler(hostingEnvironment, httpContextAccessor);
|
||||
backOfficeInfo = new AspNetCoreBackOfficeInfo(globalSettings);
|
||||
profiler = GetWebProfiler(hostingEnvironment, httpContextAccessor);
|
||||
|
||||
Current.Initialize(logger, configs, ioHelper, hostingEnvironment, backOfficeInfo, profiler);
|
||||
}
|
||||
@@ -170,5 +180,7 @@ namespace Umbraco.Web.BackOffice.AspNetCore
|
||||
// nothing to check
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
+25
-39
@@ -3775,7 +3775,7 @@
|
||||
"domelementtype": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz",
|
||||
"integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==",
|
||||
"integrity": "sha1-H4vf6R9aeAYydOgDtL3O326U+U0=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
@@ -4233,7 +4233,7 @@
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
@@ -4287,13 +4287,13 @@
|
||||
"ansi-regex": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
|
||||
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
|
||||
"integrity": "sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc=",
|
||||
"dev": true
|
||||
},
|
||||
"glob-parent": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz",
|
||||
"integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==",
|
||||
"integrity": "sha1-X0wdHnSNMM1zrSlEs1d6gbCB6MI=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-glob": "^4.0.1"
|
||||
@@ -4321,19 +4321,19 @@
|
||||
"resolve-from": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
||||
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
|
||||
"integrity": "sha1-SrzYUq0y3Xuqv+m0DgCjbbXzkuY=",
|
||||
"dev": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
||||
"integrity": "sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0=",
|
||||
"dev": true
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
|
||||
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
|
||||
"integrity": "sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^4.1.0"
|
||||
@@ -4833,7 +4833,7 @@
|
||||
"braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"integrity": "sha1-NFThpGLujVmeI23zNs2epPiv4Qc=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fill-range": "^7.0.1"
|
||||
@@ -4842,7 +4842,7 @@
|
||||
"fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"integrity": "sha1-GRmmp8df44ssfHflGYU12prN2kA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
@@ -4851,7 +4851,7 @@
|
||||
"glob-parent": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz",
|
||||
"integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==",
|
||||
"integrity": "sha1-X0wdHnSNMM1zrSlEs1d6gbCB6MI=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-glob": "^4.0.1"
|
||||
@@ -4869,13 +4869,13 @@
|
||||
"is-number": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"integrity": "sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss=",
|
||||
"dev": true
|
||||
},
|
||||
"micromatch": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
|
||||
"integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
|
||||
"integrity": "sha1-T8sJmb+fvC/L3SEvbWKbmlbDklk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"braces": "^3.0.1",
|
||||
@@ -4885,7 +4885,7 @@
|
||||
"to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"integrity": "sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-number": "^7.0.0"
|
||||
@@ -5203,7 +5203,7 @@
|
||||
"debug": {
|
||||
"version": "3.2.6",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
|
||||
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
|
||||
"integrity": "sha1-6D0X3hbYp++3cX7b5fsQE17uYps=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
@@ -5400,14 +5400,12 @@
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
@@ -5422,20 +5420,17 @@
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
@@ -5552,8 +5547,7 @@
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
@@ -5565,7 +5559,6 @@
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
@@ -5580,7 +5573,6 @@
|
||||
"version": "3.0.4",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
@@ -5588,14 +5580,12 @@
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.3.5",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.2",
|
||||
"yallist": "^3.0.0"
|
||||
@@ -5614,7 +5604,6 @@
|
||||
"version": "0.5.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
@@ -5695,8 +5684,7 @@
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
@@ -5708,7 +5696,6 @@
|
||||
"version": "1.4.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
@@ -5830,7 +5817,6 @@
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
@@ -6193,7 +6179,7 @@
|
||||
"ignore": {
|
||||
"version": "5.1.4",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz",
|
||||
"integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==",
|
||||
"integrity": "sha1-hLez2+ZFUrbvDsqZ9nQ9vsbZet8=",
|
||||
"dev": true
|
||||
},
|
||||
"slash": {
|
||||
@@ -8863,7 +8849,7 @@
|
||||
"semver": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
||||
"integrity": "sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
@@ -13046,13 +13032,13 @@
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=",
|
||||
"dev": true
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
|
||||
"integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
|
||||
"integrity": "sha1-B2Srxpxj1ayELdSGfo0CXogN+PM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
|
||||
@@ -17,14 +17,29 @@ namespace Umbraco.Web.UI.BackOffice
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
private readonly IWebHostEnvironment _webHostEnvironment;
|
||||
private readonly IConfiguration _config;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="webHostEnvironment"></param>
|
||||
/// <param name="config"></param>
|
||||
/// <remarks>
|
||||
/// Only a few services are possible to be injected here https://github.com/dotnet/aspnetcore/issues/9337
|
||||
/// </remarks>
|
||||
public Startup(IWebHostEnvironment webHostEnvironment, IConfiguration config)
|
||||
{
|
||||
_webHostEnvironment = webHostEnvironment ?? throw new ArgumentNullException(nameof(webHostEnvironment));
|
||||
_config = config ?? throw new ArgumentNullException(nameof(config));
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
|
||||
services.AddUmbracoConfiguration();
|
||||
services.AddUmbracoCore();
|
||||
services.AddUmbracoConfiguration(_config);
|
||||
services.AddUmbracoCore(_webHostEnvironment);
|
||||
services.AddUmbracoWebsite();
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace Umbraco.Web.Website.AspNetCore
|
||||
{
|
||||
public static IServiceCollection AddUmbracoWebsite(this IServiceCollection services)
|
||||
{
|
||||
// TODO: We need to avoid this, surely there's a way? See ContainerTests.BuildServiceProvider_Before_Host_Is_Configured
|
||||
var serviceProvider = services.BuildServiceProvider();
|
||||
var configs = serviceProvider.GetService<Configs>();
|
||||
var imagingSettings = configs.Imaging();
|
||||
|
||||
@@ -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 AspNetApplicationShutdownRegistry : IApplicationShutdownRegistry
|
||||
{
|
||||
private readonly ConcurrentDictionary<IRegisteredObject, RegisteredObjectWrapper> _registeredObjects =
|
||||
new ConcurrentDictionary<IRegisteredObject, RegisteredObjectWrapper>();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<IRegisteredObject, RegisteredObjectWrapper> _registeredObjects =
|
||||
new ConcurrentDictionary<IRegisteredObject, RegisteredObjectWrapper>();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.Web;
|
||||
using Umbraco.Core.Session;
|
||||
using Umbraco.Net;
|
||||
using Umbraco.Core.Session;
|
||||
|
||||
namespace Umbraco.Web.AspNet
|
||||
{
|
||||
|
||||
@@ -7,10 +7,10 @@ using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Net;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Services.Implement;
|
||||
using Umbraco.Net;
|
||||
using Umbraco.Web.Security;
|
||||
|
||||
namespace Umbraco.Core.Compose
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user