Refactor runtimes, injection and composition
This commit is contained in:
@@ -4,10 +4,6 @@ namespace Umbraco.Core.Cache
|
||||
{
|
||||
public class CacheRefresherCollectionBuilder : LazyCollectionBuilderBase<CacheRefresherCollectionBuilder, CacheRefresherCollection, ICacheRefresher>
|
||||
{
|
||||
public CacheRefresherCollectionBuilder(IContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
protected override CacheRefresherCollectionBuilder This => this;
|
||||
}
|
||||
}
|
||||
|
||||
+40
-47
@@ -13,25 +13,26 @@ namespace Umbraco.Core.Components
|
||||
{
|
||||
// note: this class is NOT thread-safe in any ways
|
||||
|
||||
internal class BootLoader
|
||||
internal class Components
|
||||
{
|
||||
private readonly IContainer _container;
|
||||
private readonly ProfilingLogger _proflog;
|
||||
private readonly ILogger _logger;
|
||||
private readonly Composition _composition;
|
||||
private readonly IProfilingLogger _logger;
|
||||
private readonly IEnumerable<Type> _componentTypes;
|
||||
private IUmbracoComponent[] _components;
|
||||
private bool _booted;
|
||||
|
||||
private const int LogThresholdMilliseconds = 100;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BootLoader"/> class.
|
||||
/// Initializes a new instance of the <see cref="Components"/> class.
|
||||
/// </summary>
|
||||
/// <param name="container">The application container.</param>
|
||||
public BootLoader(IContainer container)
|
||||
/// <param name="composition">The composition.</param>
|
||||
/// <param name="componentTypes">The component types.</param>
|
||||
/// <param name="logger">A profiling logger.</param>
|
||||
public Components(Composition composition, IEnumerable<Type> componentTypes, IProfilingLogger logger)
|
||||
{
|
||||
_container = container ?? throw new ArgumentNullException(nameof(container));
|
||||
_proflog = container.GetInstance<ProfilingLogger>();
|
||||
_logger = container.GetInstance<ILogger>();
|
||||
_composition = composition ?? throw new ArgumentNullException(nameof(composition));
|
||||
_componentTypes = componentTypes ?? throw new ArgumentNullException(nameof(componentTypes));
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
|
||||
private class EnableInfo
|
||||
@@ -40,44 +41,42 @@ namespace Umbraco.Core.Components
|
||||
public int Weight = -1;
|
||||
}
|
||||
|
||||
public void Boot(IEnumerable<Type> componentTypes, RuntimeLevel level)
|
||||
public void Compose()
|
||||
{
|
||||
if (_booted) throw new InvalidOperationException("Can not boot, has already booted.");
|
||||
|
||||
var orderedComponentTypes = PrepareComponentTypes(componentTypes, level);
|
||||
var orderedComponentTypes = PrepareComponentTypes();
|
||||
|
||||
InstantiateComponents(orderedComponentTypes);
|
||||
ComposeComponents(level);
|
||||
ComposeComponents();
|
||||
}
|
||||
|
||||
using (var scope = _container.GetInstance<IScopeProvider>().CreateScope())
|
||||
public void Initialize()
|
||||
{
|
||||
using (var scope = _composition.Container.GetInstance<IScopeProvider>().CreateScope())
|
||||
{
|
||||
InitializeComponents();
|
||||
scope.Complete();
|
||||
}
|
||||
|
||||
// rejoice!
|
||||
_booted = true;
|
||||
}
|
||||
|
||||
private IEnumerable<Type> PrepareComponentTypes(IEnumerable<Type> componentTypes, RuntimeLevel level)
|
||||
private IEnumerable<Type> PrepareComponentTypes()
|
||||
{
|
||||
using (_proflog.DebugDuration<BootLoader>("Preparing component types.", "Prepared component types."))
|
||||
using (_logger.DebugDuration<Components>("Preparing component types.", "Prepared component types."))
|
||||
{
|
||||
return PrepareComponentTypes2(componentTypes, level);
|
||||
return PrepareComponentTypes2();
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<Type> PrepareComponentTypes2(IEnumerable<Type> componentTypes, RuntimeLevel level)
|
||||
private IEnumerable<Type> PrepareComponentTypes2()
|
||||
{
|
||||
// create a list, remove those that cannot be enabled due to runtime level
|
||||
var componentTypeList = componentTypes
|
||||
var componentTypeList = _componentTypes
|
||||
.Where(x =>
|
||||
{
|
||||
// use the min level specified by the attribute if any
|
||||
// otherwise, user components have Run min level, anything else is Unknown (always run)
|
||||
var attr = x.GetCustomAttribute<RuntimeLevelAttribute>();
|
||||
var minLevel = attr?.MinLevel ?? (x.Implements<IUmbracoUserComponent>() ? RuntimeLevel.Run : RuntimeLevel.Unknown);
|
||||
return level >= minLevel;
|
||||
return _composition.RuntimeLevel >= minLevel;
|
||||
})
|
||||
.ToList();
|
||||
|
||||
@@ -107,15 +106,15 @@ namespace Umbraco.Core.Components
|
||||
catch (Exception e)
|
||||
{
|
||||
// in case of an error, force-dump everything to log
|
||||
_logger.Info<BootLoader>("Component Report:\r\n{ComponentReport}", GetComponentsReport(requirements));
|
||||
_logger.Error<BootLoader>(e, "Failed to sort components.");
|
||||
_logger.Info<Components>("Component Report:\r\n{ComponentReport}", GetComponentsReport(requirements));
|
||||
_logger.Error<Components>(e, "Failed to sort components.");
|
||||
throw;
|
||||
}
|
||||
|
||||
// bit verbose but should help for troubleshooting
|
||||
var text = "Ordered Components: " + Environment.NewLine + string.Join(Environment.NewLine, sortedComponentTypes) + Environment.NewLine;
|
||||
Console.WriteLine(text);
|
||||
_logger.Debug<BootLoader>("Ordered Components: {SortedComponentTypes}", sortedComponentTypes);
|
||||
_logger.Debug<Components>("Ordered Components: {SortedComponentTypes}", sortedComponentTypes);
|
||||
|
||||
return sortedComponentTypes;
|
||||
}
|
||||
@@ -275,23 +274,23 @@ namespace Umbraco.Core.Components
|
||||
|
||||
private void InstantiateComponents(IEnumerable<Type> types)
|
||||
{
|
||||
using (_proflog.DebugDuration<BootLoader>("Instantiating components.", "Instantiated components."))
|
||||
using (_logger.DebugDuration<Components>("Instantiating components.", "Instantiated components."))
|
||||
{
|
||||
// fixme is there a faster way?
|
||||
_components = types.Select(x => (IUmbracoComponent) Activator.CreateInstance(x)).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
private void ComposeComponents(RuntimeLevel level)
|
||||
private void ComposeComponents()
|
||||
{
|
||||
using (_proflog.DebugDuration<BootLoader>($"Composing components. (log when >{LogThresholdMilliseconds}ms)", "Composed components."))
|
||||
using (_logger.DebugDuration<Components>($"Composing components. (log when >{LogThresholdMilliseconds}ms)", "Composed components."))
|
||||
{
|
||||
var composition = new Composition(_container, level);
|
||||
foreach (var component in _components)
|
||||
{
|
||||
var componentType = component.GetType();
|
||||
using (_proflog.DebugDuration<BootLoader>($"Composing {componentType.FullName}.", $"Composed {componentType.FullName}.", thresholdMilliseconds: LogThresholdMilliseconds))
|
||||
using (_logger.DebugDuration<Components>($"Composing {componentType.FullName}.", $"Composed {componentType.FullName}.", thresholdMilliseconds: LogThresholdMilliseconds))
|
||||
{
|
||||
component.Compose(composition);
|
||||
component.Compose(_composition);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -301,15 +300,15 @@ namespace Umbraco.Core.Components
|
||||
{
|
||||
// use a container scope to ensure that PerScope instances are disposed
|
||||
// components that require instances that should not survive should register them with PerScope lifetime
|
||||
using (_proflog.DebugDuration<BootLoader>($"Initializing components. (log when >{LogThresholdMilliseconds}ms)", "Initialized components."))
|
||||
using (_container.BeginScope())
|
||||
using (_logger.DebugDuration<Components>($"Initializing components. (log when >{LogThresholdMilliseconds}ms)", "Initialized components."))
|
||||
using (_composition.Container.BeginScope())
|
||||
{
|
||||
foreach (var component in _components)
|
||||
{
|
||||
var componentType = component.GetType();
|
||||
var initializers = componentType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
|
||||
.Where(x => x.Name == "Initialize" && x.IsGenericMethod == false && x.IsStatic == false);
|
||||
using (_proflog.DebugDuration<BootLoader>($"Initializing {componentType.FullName}.", $"Initialized {componentType.FullName}.", thresholdMilliseconds: LogThresholdMilliseconds))
|
||||
using (_logger.DebugDuration<Components>($"Initializing {componentType.FullName}.", $"Initialized {componentType.FullName}.", thresholdMilliseconds: LogThresholdMilliseconds))
|
||||
{
|
||||
foreach (var initializer in initializers)
|
||||
{
|
||||
@@ -329,7 +328,7 @@ namespace Umbraco.Core.Components
|
||||
|
||||
try
|
||||
{
|
||||
param = _container.TryGetInstance(parameterType);
|
||||
param = _composition.Container.TryGetInstance(parameterType);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -342,19 +341,13 @@ namespace Umbraco.Core.Components
|
||||
|
||||
public void Terminate()
|
||||
{
|
||||
if (_booted == false)
|
||||
{
|
||||
_proflog.Logger.Warn<BootLoader>("Cannot terminate, has not booted.");
|
||||
return;
|
||||
}
|
||||
|
||||
using (_proflog.DebugDuration<BootLoader>($"Terminating. (log components when >{LogThresholdMilliseconds}ms)", "Terminated."))
|
||||
using (_logger.DebugDuration<Components>($"Terminating. (log components when >{LogThresholdMilliseconds}ms)", "Terminated."))
|
||||
{
|
||||
for (var i = _components.Length - 1; i >= 0; i--) // terminate components in reverse order
|
||||
{
|
||||
var component = _components[i];
|
||||
var componentType = component.GetType();
|
||||
using (_proflog.DebugDuration<BootLoader>($"Terminating {componentType.FullName}.", $"Terminated {componentType.FullName}.", thresholdMilliseconds: LogThresholdMilliseconds))
|
||||
using (_logger.DebugDuration<Components>($"Terminating {componentType.FullName}.", $"Terminated {componentType.FullName}.", thresholdMilliseconds: LogThresholdMilliseconds))
|
||||
{
|
||||
component.Terminate();
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using Umbraco.Core.Composing;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.Components
|
||||
{
|
||||
@@ -12,6 +14,8 @@ namespace Umbraco.Core.Components
|
||||
/// may cause issues.</remarks>
|
||||
public class Composition
|
||||
{
|
||||
private readonly Dictionary<Type, ICollectionBuilder> _builders = new Dictionary<Type, ICollectionBuilder>();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Composition"/> class.
|
||||
/// </summary>
|
||||
@@ -33,5 +37,26 @@ namespace Umbraco.Core.Components
|
||||
/// Gets the runtime level.
|
||||
/// </summary>
|
||||
public RuntimeLevel RuntimeLevel { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection builder (and registers the collection).
|
||||
/// </summary>
|
||||
/// <typeparam name="TBuilder">The type of the collection builder.</typeparam>
|
||||
/// <returns>The collection builder.</returns>
|
||||
public TBuilder GetCollectionBuilder<TBuilder>()
|
||||
where TBuilder: ICollectionBuilder, new()
|
||||
{
|
||||
var typeOfBuilder = typeof(TBuilder);
|
||||
|
||||
if (_builders.TryGetValue(typeOfBuilder, out var o))
|
||||
return (TBuilder) o;
|
||||
|
||||
var builder = new TBuilder();
|
||||
builder.Initialize(Container);
|
||||
|
||||
_builders[typeOfBuilder] = builder;
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,25 +16,12 @@ namespace Umbraco.Core.Composing
|
||||
{
|
||||
private readonly List<Type> _types = new List<Type>();
|
||||
private readonly object _locker = new object();
|
||||
private Func<IEnumerable<TItem>, TCollection> _collectionCtor;
|
||||
private Type[] _registeredTypes;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CollectionBuilderBase{TBuilder, TCollection,TItem}"/>
|
||||
/// class with a service container.
|
||||
/// </summary>
|
||||
/// <param name="container">A container.</param>
|
||||
protected CollectionBuilderBase(IContainer container)
|
||||
{
|
||||
Container = container;
|
||||
// ReSharper disable once DoNotCallOverridableMethodsInConstructor
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the container.
|
||||
/// </summary>
|
||||
protected IContainer Container { get; }
|
||||
protected IContainer Container { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the internal list of types as an IEnumerable (immutable).
|
||||
@@ -44,17 +31,13 @@ namespace Umbraco.Core.Composing
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the builder.
|
||||
/// </summary>
|
||||
/// <remarks>This is called by the constructor and, by default, registers the
|
||||
/// collection automatically.</remarks>
|
||||
protected virtual void Initialize()
|
||||
/// <remarks>By default, this registers the collection automatically.</remarks>
|
||||
public virtual void Initialize(IContainer container)
|
||||
{
|
||||
// compile the auto-collection constructor
|
||||
// can be null, if no ctor found, and then assume CreateCollection has been overriden
|
||||
_collectionCtor = ReflectionUtilities.EmitConstructor<Func<IEnumerable<TItem>, TCollection>>(mustExist: false);
|
||||
if (Container != null)
|
||||
throw new InvalidOperationException("This builder has already been initialized.");
|
||||
|
||||
// we just don't want to support re-registering collections here
|
||||
if (Container.GetRegistered<TCollection>().Any())
|
||||
throw new InvalidOperationException("Collection builders cannot be registered once the collection itself has been registered.");
|
||||
Container = container;
|
||||
|
||||
// register the collection
|
||||
Container.Register(_ => CreateCollection(), CollectionLifetime);
|
||||
@@ -131,8 +114,7 @@ namespace Umbraco.Core.Composing
|
||||
/// <remarks>Creates a new collection each time it is invoked.</remarks>
|
||||
public virtual TCollection CreateCollection()
|
||||
{
|
||||
if (_collectionCtor == null) throw new InvalidOperationException("Collection auto-creation is not possible.");
|
||||
return _collectionCtor(CreateItems());
|
||||
return Container.CreateInstance<TCollection>(CreateItems());
|
||||
}
|
||||
|
||||
protected Type EnsureType(Type type, string action)
|
||||
|
||||
@@ -97,26 +97,6 @@ namespace Umbraco.Core.Composing
|
||||
public static void RegisterAuto<TServiceBase>(this IContainer container)
|
||||
=> container.RegisterAuto(typeof(TServiceBase));
|
||||
|
||||
/// <summary>
|
||||
/// Registers and instantiates a collection builder.
|
||||
/// </summary>
|
||||
/// <typeparam name="TBuilder">The type of the collection builder.</typeparam>
|
||||
/// <returns>A collection builder of the specified type.</returns>
|
||||
public static TBuilder RegisterCollectionBuilder<TBuilder>(this IContainer container)
|
||||
{
|
||||
// make sure it's not already registered
|
||||
// we just don't want to support re-registering collection builders
|
||||
if (container.GetRegistered<TBuilder>().Any())
|
||||
throw new InvalidOperationException("Collection builders should be registered only once.");
|
||||
|
||||
// register the builder
|
||||
// use a factory so we don't have to self-register the container
|
||||
container.RegisterSingleton(factory => factory.CreateInstance<TBuilder>(container));
|
||||
|
||||
// initialize and return the builder
|
||||
return container.GetInstance<TBuilder>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of a service, with arguments.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,11 +1,22 @@
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a collection builder.
|
||||
/// </summary>
|
||||
public interface ICollectionBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the builder, and registers the collection.
|
||||
/// </summary>
|
||||
void Initialize(IContainer container);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a collection builder.
|
||||
/// </summary>
|
||||
/// <typeparam name="TCollection">The type of the collection.</typeparam>
|
||||
/// <typeparam name="TItem">The type of the items.</typeparam>
|
||||
public interface ICollectionBuilder<out TCollection, TItem>
|
||||
public interface ICollectionBuilder<out TCollection, TItem> : ICollectionBuilder
|
||||
where TCollection : IBuilderCollection<TItem>
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -18,19 +18,12 @@ namespace Umbraco.Core.Composing
|
||||
private readonly List<Func<IContainer, IEnumerable<Type>>> _producers2 = new List<Func<IContainer, IEnumerable<Type>>>();
|
||||
private readonly List<Type> _excluded = new List<Type>();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LazyCollectionBuilderBase{TBuilder,TCollection,TItem}"/> class.
|
||||
/// </summary>
|
||||
protected LazyCollectionBuilderBase(IContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
protected abstract TBuilder This { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Clears all types in the collection.
|
||||
/// </summary>
|
||||
/// <returns>The buidler.</returns>
|
||||
/// <returns>The builder.</returns>
|
||||
public TBuilder Clear()
|
||||
{
|
||||
Configure(types =>
|
||||
|
||||
@@ -13,20 +13,12 @@ namespace Umbraco.Core.Composing
|
||||
where TBuilder : OrderedCollectionBuilderBase<TBuilder, TCollection, TItem>
|
||||
where TCollection : IBuilderCollection<TItem>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OrderedCollectionBuilderBase{TBuilder,TCollection,TItem}"/> class.
|
||||
/// </summary>
|
||||
/// <param name="container"></param>
|
||||
protected OrderedCollectionBuilderBase(IContainer container)
|
||||
: base (container)
|
||||
{ }
|
||||
|
||||
protected abstract TBuilder This { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Clears all types in the collection.
|
||||
/// </summary>
|
||||
/// <returns>The buidler.</returns>
|
||||
/// <returns>The builder.</returns>
|
||||
public TBuilder Clear()
|
||||
{
|
||||
Configure(types => types.Clear());
|
||||
|
||||
@@ -16,7 +16,7 @@ using File = System.IO.File;
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides methods to find and instanciate types.
|
||||
/// Provides methods to find and instantiate types.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>This class should be used to get all types, the <see cref="TypeFinder"/> class should never be used directly.</para>
|
||||
@@ -30,7 +30,7 @@ namespace Umbraco.Core.Composing
|
||||
|
||||
private readonly IRuntimeCacheProvider _runtimeCache;
|
||||
private readonly IGlobalSettings _globalSettings;
|
||||
private readonly ProfilingLogger _logger;
|
||||
private readonly IProfilingLogger _logger;
|
||||
|
||||
private readonly object _typesLock = new object();
|
||||
private readonly Dictionary<TypeListKey, TypeList> _types = new Dictionary<TypeListKey, TypeList>();
|
||||
@@ -49,7 +49,7 @@ namespace Umbraco.Core.Composing
|
||||
/// <param name="globalSettings"></param>
|
||||
/// <param name="logger">A profiling logger.</param>
|
||||
/// <param name="detectChanges">Whether to detect changes using hashes.</param>
|
||||
internal TypeLoader(IRuntimeCacheProvider runtimeCache, IGlobalSettings globalSettings, ProfilingLogger logger, bool detectChanges = true)
|
||||
internal TypeLoader(IRuntimeCacheProvider runtimeCache, IGlobalSettings globalSettings, IProfilingLogger logger, bool detectChanges = true)
|
||||
{
|
||||
_runtimeCache = runtimeCache ?? throw new ArgumentNullException(nameof(runtimeCache));
|
||||
_globalSettings = globalSettings ?? throw new ArgumentNullException(nameof(globalSettings));
|
||||
@@ -192,7 +192,7 @@ namespace Umbraco.Core.Composing
|
||||
/// <returns>The hash.</returns>
|
||||
/// <remarks>Each file is a tuple containing the FileInfo object and a boolean which indicates whether to hash the
|
||||
/// file properties (false) or the file contents (true).</remarks>
|
||||
private static string GetFileHash(IEnumerable<Tuple<FileSystemInfo, bool>> filesAndFolders, ProfilingLogger logger)
|
||||
private static string GetFileHash(IEnumerable<Tuple<FileSystemInfo, bool>> filesAndFolders, IProfilingLogger logger)
|
||||
{
|
||||
using (logger.TraceDuration<TypeLoader>("Determining hash of code files on disk", "Hash determined"))
|
||||
{
|
||||
@@ -494,7 +494,7 @@ namespace Umbraco.Core.Composing
|
||||
if (--attempts == 0)
|
||||
throw;
|
||||
|
||||
_logger.Logger.Debug<TypeLoader>("Attempted to get filestream for file {Path} failed, {NumberOfAttempts} attempts left, pausing for {PauseMilliseconds} milliseconds", path, attempts, pauseMilliseconds);
|
||||
_logger.Debug<TypeLoader>("Attempted to get filestream for file {Path} failed, {NumberOfAttempts} attempts left, pausing for {PauseMilliseconds} milliseconds", path, attempts, pauseMilliseconds);
|
||||
Thread.Sleep(pauseMilliseconds);
|
||||
}
|
||||
}
|
||||
@@ -645,7 +645,7 @@ namespace Umbraco.Core.Composing
|
||||
if (typeList != null)
|
||||
{
|
||||
// need to put some logging here to try to figure out why this is happening: http://issues.umbraco.org/issue/U4-3505
|
||||
_logger.Logger.Debug<TypeLoader>("Getting {TypeName}: found a cached type list.", GetName(baseType, attributeType));
|
||||
_logger.Debug<TypeLoader>("Getting {TypeName}: found a cached type list.", GetName(baseType, attributeType));
|
||||
return typeList.Types;
|
||||
}
|
||||
|
||||
@@ -661,7 +661,7 @@ namespace Umbraco.Core.Composing
|
||||
// report (only once) and scan and update the cache file
|
||||
if (_reportedChange == false)
|
||||
{
|
||||
_logger.Logger.Debug<TypeLoader>("Assemblies changes detected, need to rescan everything.");
|
||||
_logger.Debug<TypeLoader>("Assemblies changes detected, need to rescan everything.");
|
||||
_reportedChange = true;
|
||||
}
|
||||
}
|
||||
@@ -676,7 +676,7 @@ namespace Umbraco.Core.Composing
|
||||
// so in this instance there will never be a result.
|
||||
if (cacheResult.Exception is CachedTypeNotFoundInFileException || cacheResult.Success == false)
|
||||
{
|
||||
_logger.Logger.Debug<TypeLoader>("Getting {TypeName}: failed to load from cache file, must scan assemblies.", GetName(baseType, attributeType));
|
||||
_logger.Debug<TypeLoader>("Getting {TypeName}: failed to load from cache file, must scan assemblies.", GetName(baseType, attributeType));
|
||||
scan = true;
|
||||
}
|
||||
else
|
||||
@@ -695,7 +695,7 @@ namespace Umbraco.Core.Composing
|
||||
catch (Exception ex)
|
||||
{
|
||||
// in case of any exception, we have to exit, and revert to scanning
|
||||
_logger.Logger.Error<TypeLoader>(ex, "Getting {TypeName}: failed to load cache file type {CacheType}, reverting to scanning assemblies.", GetName(baseType, attributeType), type);
|
||||
_logger.Error<TypeLoader>(ex, "Getting {TypeName}: failed to load cache file type {CacheType}, reverting to scanning assemblies.", GetName(baseType, attributeType), type);
|
||||
scan = true;
|
||||
break;
|
||||
}
|
||||
@@ -703,7 +703,7 @@ namespace Umbraco.Core.Composing
|
||||
|
||||
if (scan == false)
|
||||
{
|
||||
_logger.Logger.Debug<TypeLoader>("Getting {TypeName}: loaded types from cache file.", GetName(baseType, attributeType));
|
||||
_logger.Debug<TypeLoader>("Getting {TypeName}: loaded types from cache file.", GetName(baseType, attributeType));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -711,7 +711,7 @@ namespace Umbraco.Core.Composing
|
||||
if (scan)
|
||||
{
|
||||
// either we had to scan, or we could not get the types from the cache file - scan now
|
||||
_logger.Logger.Debug<TypeLoader>("Getting {TypeName}: scanning assemblies.", GetName(baseType, attributeType));
|
||||
_logger.Debug<TypeLoader>("Getting {TypeName}: scanning assemblies.", GetName(baseType, attributeType));
|
||||
|
||||
foreach (var t in finder())
|
||||
typeList.Add(t);
|
||||
@@ -729,11 +729,11 @@ namespace Umbraco.Core.Composing
|
||||
UpdateCache();
|
||||
}
|
||||
|
||||
_logger.Logger.Debug<TypeLoader>("Got {TypeName}, caching ({CacheType}).", GetName(baseType, attributeType), added.ToString().ToLowerInvariant());
|
||||
_logger.Debug<TypeLoader>("Got {TypeName}, caching ({CacheType}).", GetName(baseType, attributeType), added.ToString().ToLowerInvariant());
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Logger.Debug<TypeLoader>("Got {TypeName}.", GetName(baseType, attributeType));
|
||||
_logger.Debug<TypeLoader>("Got {TypeName}.", GetName(baseType, attributeType));
|
||||
}
|
||||
|
||||
return typeList.Types;
|
||||
|
||||
@@ -42,13 +42,5 @@ namespace Umbraco.Core.Composing
|
||||
{
|
||||
return mgr.GetTypesWithAttribute<BaseMapper, MapperForAttribute>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all classes implementing ISqlSyntaxProvider and marked with the SqlSyntaxProviderAttribute.
|
||||
/// </summary>
|
||||
public static IEnumerable<Type> GetSqlSyntaxProviders(this TypeLoader mgr)
|
||||
{
|
||||
return mgr.GetTypesWithAttribute<ISqlSyntaxProvider, SqlSyntaxProviderAttribute>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,20 +14,12 @@ namespace Umbraco.Core.Composing
|
||||
where TBuilder : WeightedCollectionBuilderBase<TBuilder, TCollection, TItem>
|
||||
where TCollection : IBuilderCollection<TItem>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WeightedCollectionBuilderBase{TBuilder,TCollection,TItem}"/> class.
|
||||
/// </summary>
|
||||
/// <param name="container"></param>
|
||||
protected WeightedCollectionBuilderBase(IContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
protected abstract TBuilder This { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Clears all types in the collection.
|
||||
/// </summary>
|
||||
/// <returns>The buidler.</returns>
|
||||
/// <returns>The builder.</returns>
|
||||
public TBuilder Clear()
|
||||
{
|
||||
Configure(types => types.Clear());
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the profiling logging service.
|
||||
/// </summary>
|
||||
public interface IProfilingLogger : ILogger
|
||||
{
|
||||
/// <summary>
|
||||
/// Profiles an action and log as information messages.
|
||||
/// </summary>
|
||||
DisposableTimer TraceDuration<T>(string startMessage);
|
||||
|
||||
/// <summary>
|
||||
/// Profiles an action and log as information messages.
|
||||
/// </summary>
|
||||
DisposableTimer TraceDuration<T>(string startMessage, string completeMessage, string failMessage = null);
|
||||
|
||||
/// <summary>
|
||||
/// Profiles an action and log as information messages.
|
||||
/// </summary>
|
||||
DisposableTimer TraceDuration(Type loggerType, string startMessage, string completeMessage, string failMessage = null);
|
||||
|
||||
/// <summary>
|
||||
/// Profiles an action and log as debug messages.
|
||||
/// </summary>
|
||||
DisposableTimer DebugDuration<T>(string startMessage);
|
||||
|
||||
/// <summary>
|
||||
/// Profiles an action and log as debug messages.
|
||||
/// </summary>
|
||||
DisposableTimer DebugDuration<T>(string startMessage, string completeMessage, string failMessage = null, int thresholdMilliseconds = 0);
|
||||
|
||||
/// <summary>
|
||||
/// Profiles an action and log as debug messages.
|
||||
/// </summary>
|
||||
DisposableTimer DebugDuration(Type loggerType, string startMessage, string completeMessage, string failMessage = null, int thresholdMilliseconds = 0);
|
||||
}
|
||||
}
|
||||
@@ -3,14 +3,23 @@
|
||||
namespace Umbraco.Core.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides debug or trace logging with duration management.
|
||||
/// Provides logging and profiling services.
|
||||
/// </summary>
|
||||
public sealed class ProfilingLogger
|
||||
public sealed class ProfilingLogger : IProfilingLogger
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the underlying <see cref="ILogger"/> implementation.
|
||||
/// </summary>
|
||||
public ILogger Logger { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the underlying <see cref="IProfiler"/> implementation.
|
||||
/// </summary>
|
||||
public IProfiler Profiler { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ProfilingLogger"/> class.
|
||||
/// </summary>
|
||||
public ProfilingLogger(ILogger logger, IProfiler profiler)
|
||||
{
|
||||
Logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
@@ -52,5 +61,72 @@ namespace Umbraco.Core.Logging
|
||||
? new DisposableTimer(Logger, LogLevel.Debug, Profiler, loggerType, startMessage, completeMessage, failMessage, thresholdMilliseconds)
|
||||
: null;
|
||||
}
|
||||
|
||||
#region ILogger
|
||||
|
||||
public bool IsEnabled(Type reporting, LogLevel level)
|
||||
=> Logger.IsEnabled(reporting, level);
|
||||
|
||||
public void Fatal(Type reporting, Exception exception, string message)
|
||||
=> Logger.Fatal(reporting, exception, message);
|
||||
|
||||
public void Fatal(Type reporting, Exception exception)
|
||||
=> Logger.Fatal(reporting, exception);
|
||||
|
||||
public void Fatal(Type reporting, string message)
|
||||
=> Logger.Fatal(reporting, message);
|
||||
|
||||
public void Fatal(Type reporting, Exception exception, string messageTemplate, params object[] propertyValues)
|
||||
=> Logger.Fatal(reporting, exception, messageTemplate, propertyValues);
|
||||
|
||||
public void Fatal(Type reporting, string messageTemplate, params object[] propertyValues)
|
||||
=> Logger.Fatal(reporting, messageTemplate, propertyValues);
|
||||
|
||||
public void Error(Type reporting, Exception exception, string message)
|
||||
=> Logger.Error(reporting, exception, message);
|
||||
|
||||
public void Error(Type reporting, Exception exception)
|
||||
=> Logger.Error(reporting, exception);
|
||||
|
||||
public void Error(Type reporting, string message)
|
||||
=> Logger.Error(reporting, message);
|
||||
|
||||
public void Error(Type reporting, Exception exception, string messageTemplate, params object[] propertyValues)
|
||||
=> Logger.Error(reporting, exception, messageTemplate, propertyValues);
|
||||
|
||||
public void Error(Type reporting, string messageTemplate, params object[] propertyValues)
|
||||
=> Logger.Error(reporting, messageTemplate, propertyValues);
|
||||
|
||||
public void Warn(Type reporting, string message)
|
||||
=> Logger.Warn(reporting, message);
|
||||
|
||||
public void Warn(Type reporting, string messageTemplate, params object[] propertyValues)
|
||||
=> Logger.Warn(reporting, messageTemplate, propertyValues);
|
||||
|
||||
public void Warn(Type reporting, Exception exception, string message)
|
||||
=> Logger.Warn(reporting, exception, message);
|
||||
|
||||
public void Warn(Type reporting, Exception exception, string messageTemplate, params object[] propertyValues)
|
||||
=> Logger.Warn(reporting, exception, messageTemplate, propertyValues);
|
||||
|
||||
public void Info(Type reporting, string message)
|
||||
=> Logger.Info(reporting, message);
|
||||
|
||||
public void Info(Type reporting, string messageTemplate, params object[] propertyValues)
|
||||
=> Logger.Info(reporting, messageTemplate, propertyValues);
|
||||
|
||||
public void Debug(Type reporting, string message)
|
||||
=> Logger.Debug(reporting, message);
|
||||
|
||||
public void Debug(Type reporting, string messageTemplate, params object[] propertyValues)
|
||||
=> Logger.Debug(reporting, messageTemplate, propertyValues);
|
||||
|
||||
public void Verbose(Type reporting, string message)
|
||||
=> Logger.Verbose(reporting, message);
|
||||
|
||||
public void Verbose(Type reporting, string messageTemplate, params object[] propertyValues)
|
||||
=> Logger.Verbose(reporting, messageTemplate, propertyValues);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -369,52 +369,6 @@ namespace Umbraco.Core.Migrations.Install
|
||||
|
||||
#endregion
|
||||
|
||||
#region Utils
|
||||
|
||||
internal static void GiveLegacyAChance(IUmbracoDatabaseFactory factory, ILogger logger)
|
||||
{
|
||||
// look for the legacy appSettings key
|
||||
var legacyConnString = ConfigurationManager.AppSettings[Constants.System.UmbracoConnectionName];
|
||||
if (string.IsNullOrWhiteSpace(legacyConnString)) return;
|
||||
|
||||
var test = legacyConnString.ToLowerInvariant();
|
||||
if (test.Contains("sqlce4umbraco"))
|
||||
{
|
||||
// sql ce
|
||||
ConfigureEmbeddedDatabaseConnection(factory, logger);
|
||||
}
|
||||
else if (test.Contains("tcp:"))
|
||||
{
|
||||
// sql azure
|
||||
SaveConnectionString(legacyConnString, Constants.DbProviderNames.SqlServer, logger);
|
||||
factory.Configure(legacyConnString, Constants.DbProviderNames.SqlServer);
|
||||
}
|
||||
else if (test.Contains("datalayer=mysql"))
|
||||
{
|
||||
// mysql
|
||||
|
||||
// strip the datalayer part off
|
||||
var connectionStringWithoutDatalayer = string.Empty;
|
||||
// ReSharper disable once LoopCanBeConvertedToQuery
|
||||
foreach (var variable in legacyConnString.Split(';').Where(x => x.ToLowerInvariant().StartsWith("datalayer") == false))
|
||||
connectionStringWithoutDatalayer = $"{connectionStringWithoutDatalayer}{variable};";
|
||||
|
||||
SaveConnectionString(connectionStringWithoutDatalayer, Constants.DbProviderNames.MySql, logger);
|
||||
factory.Configure(connectionStringWithoutDatalayer, Constants.DbProviderNames.MySql);
|
||||
}
|
||||
else
|
||||
{
|
||||
// sql server
|
||||
SaveConnectionString(legacyConnString, Constants.DbProviderNames.SqlServer, logger);
|
||||
factory.Configure(legacyConnString, Constants.DbProviderNames.SqlServer);
|
||||
}
|
||||
|
||||
// remove the legacy connection string, so we don't end up in a loop if something goes wrong
|
||||
GlobalSettings.RemoveSetting(Constants.System.UmbracoConnectionName);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Database Schema
|
||||
|
||||
internal DatabaseSchemaResult ValidateDatabaseSchema()
|
||||
|
||||
@@ -4,10 +4,6 @@ namespace Umbraco.Core.Migrations
|
||||
{
|
||||
public class PostMigrationCollectionBuilder : LazyCollectionBuilderBase<PostMigrationCollectionBuilder, PostMigrationCollection, IPostMigration>
|
||||
{
|
||||
public PostMigrationCollectionBuilder(IContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
protected override PostMigrationCollectionBuilder This => this;
|
||||
|
||||
protected override Lifetime CollectionLifetime => Lifetime.Transient;
|
||||
|
||||
@@ -4,15 +4,11 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
{
|
||||
public class MapperCollectionBuilder : LazyCollectionBuilderBase<MapperCollectionBuilder, MapperCollection, BaseMapper>
|
||||
{
|
||||
public MapperCollectionBuilder(IContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
protected override MapperCollectionBuilder This => this;
|
||||
|
||||
protected override void Initialize()
|
||||
public override void Initialize(IContainer container)
|
||||
{
|
||||
base.Initialize();
|
||||
base.Initialize(container);
|
||||
|
||||
// default initializer registers
|
||||
// - service MapperCollectionBuilder, returns MapperCollectionBuilder
|
||||
@@ -23,7 +19,7 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
Container.Register<IMapperCollection>(factory => factory.GetInstance<MapperCollection>());
|
||||
}
|
||||
|
||||
public MapperCollectionBuilder AddCore()
|
||||
public MapperCollectionBuilder AddCoreMappers()
|
||||
{
|
||||
Add<AccessMapper>();
|
||||
Add<AuditItemMapper>();
|
||||
|
||||
@@ -11,7 +11,6 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
/// <summary>
|
||||
/// Represents an SqlSyntaxProvider for MySql
|
||||
/// </summary>
|
||||
[SqlSyntaxProvider(Constants.DbProviderNames.MySql)]
|
||||
public class MySqlSyntaxProvider : SqlSyntaxProviderBase<MySqlSyntaxProvider>
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
@@ -334,7 +333,7 @@ ORDER BY TABLE_NAME, INDEX_NAME",
|
||||
switch (systemMethod)
|
||||
{
|
||||
case SystemMethods.NewGuid:
|
||||
return null; // NOT SUPPORTED!
|
||||
return null; // NOT SUPPORTED!
|
||||
case SystemMethods.CurrentDateTime:
|
||||
return "CURRENT_TIMESTAMP";
|
||||
}
|
||||
|
||||
@@ -4,14 +4,12 @@ using System.Linq;
|
||||
using NPoco;
|
||||
using Umbraco.Core.Persistence.DatabaseAnnotations;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
|
||||
namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an SqlSyntaxProvider for Sql Ce
|
||||
/// </summary>
|
||||
[SqlSyntaxProvider(Constants.DbProviderNames.SqlCe)]
|
||||
public class SqlCeSyntaxProvider : MicrosoftSqlSyntaxProviderBase<SqlCeSyntaxProvider>
|
||||
{
|
||||
public override Sql<ISqlContext> SelectTop(Sql<ISqlContext> sql, int top)
|
||||
|
||||
@@ -11,29 +11,9 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
/// <summary>
|
||||
/// Represents an SqlSyntaxProvider for Sql Server.
|
||||
/// </summary>
|
||||
[SqlSyntaxProvider(Constants.DbProviderNames.SqlServer)]
|
||||
public class SqlServerSyntaxProvider : MicrosoftSqlSyntaxProviderBase<SqlServerSyntaxProvider>
|
||||
{
|
||||
// IUmbracoDatabaseFactory to be lazily injected
|
||||
public SqlServerSyntaxProvider(Lazy<IScopeProvider> lazyScopeProvider)
|
||||
{
|
||||
_serverVersion = new Lazy<ServerVersionInfo>(() =>
|
||||
{
|
||||
var scopeProvider = lazyScopeProvider.Value;
|
||||
if (scopeProvider == null)
|
||||
throw new InvalidOperationException("Failed to determine Sql Server version (no scope provider).");
|
||||
using (var scope = scopeProvider.CreateScope())
|
||||
{
|
||||
var version = DetermineVersion(scope.Database);
|
||||
scope.Complete();
|
||||
return version;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private readonly Lazy<ServerVersionInfo> _serverVersion;
|
||||
|
||||
internal ServerVersionInfo ServerVersion => _serverVersion.Value;
|
||||
internal ServerVersionInfo ServerVersion { get; private set; }
|
||||
|
||||
internal enum VersionName
|
||||
{
|
||||
@@ -62,19 +42,31 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
|
||||
internal class ServerVersionInfo
|
||||
{
|
||||
public string Edition { get; set; }
|
||||
public string InstanceName { get; set; }
|
||||
public string ProductVersion { get; set; }
|
||||
public VersionName ProductVersionName { get; private set; }
|
||||
public EngineEdition EngineEdition { get; set; }
|
||||
public bool IsAzure => EngineEdition == EngineEdition.Azure;
|
||||
public string MachineName { get; set; }
|
||||
public string ProductLevel { get; set; }
|
||||
|
||||
public void Initialize()
|
||||
public ServerVersionInfo()
|
||||
{
|
||||
ProductVersionName = MapProductVersion(ProductVersion);
|
||||
ProductVersionName = VersionName.Unknown;
|
||||
EngineEdition = EngineEdition.Unknown;
|
||||
}
|
||||
|
||||
public ServerVersionInfo(string edition, string instanceName, string productVersion, EngineEdition engineEdition, string machineName, string productLevel)
|
||||
{
|
||||
Edition = edition;
|
||||
InstanceName = instanceName;
|
||||
ProductVersion = productVersion;
|
||||
ProductVersionName = MapProductVersion(ProductVersion);
|
||||
EngineEdition = engineEdition;
|
||||
MachineName = machineName;
|
||||
ProductLevel = productLevel;
|
||||
}
|
||||
|
||||
public string Edition { get; }
|
||||
public string InstanceName { get; }
|
||||
public string ProductVersion { get; }
|
||||
public VersionName ProductVersionName { get; }
|
||||
public EngineEdition EngineEdition { get; }
|
||||
public bool IsAzure => EngineEdition == EngineEdition.Azure;
|
||||
public string MachineName { get; }
|
||||
public string ProductLevel { get; }
|
||||
}
|
||||
|
||||
private static VersionName MapProductVersion(string productVersion)
|
||||
@@ -105,8 +97,14 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
}
|
||||
}
|
||||
|
||||
private static ServerVersionInfo DetermineVersion(IUmbracoDatabase database)
|
||||
internal ServerVersionInfo GetSetVersion(string connectionString, string providerName)
|
||||
{
|
||||
var factory = DbProviderFactories.GetFactory(providerName);
|
||||
var connection = factory.CreateConnection();
|
||||
|
||||
if (connection == null)
|
||||
throw new InvalidOperationException($"Could not create a connection for provider \"{providerName}\".");
|
||||
|
||||
// Edition: "Express Edition", "Windows Azure SQL Database..."
|
||||
// EngineEdition: 1/Desktop 2/Standard 3/Enterprise 4/Express 5/Azure
|
||||
// ProductLevel: RTM, SPx, CTP...
|
||||
@@ -123,44 +121,28 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
SERVERPROPERTY('ResourceLastUpdateDateTime') ResourceLastUpdateDateTime,
|
||||
SERVERPROPERTY('ProductLevel') ProductLevel;";
|
||||
|
||||
try
|
||||
{
|
||||
var version = database.Fetch<ServerVersionInfo>(sql).First();
|
||||
version.Initialize();
|
||||
return version;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// can't ignore, really
|
||||
throw new Exception("Failed to determine Sql Server version (see inner exception).", e);
|
||||
}
|
||||
}
|
||||
|
||||
internal static VersionName GetVersionName(string connectionString, string providerName)
|
||||
{
|
||||
var factory = DbProviderFactories.GetFactory(providerName);
|
||||
var connection = factory.CreateConnection();
|
||||
|
||||
if (connection == null)
|
||||
throw new InvalidOperationException($"Could not create a connection for provider \"{providerName}\".");
|
||||
|
||||
connection.ConnectionString = connectionString;
|
||||
ServerVersionInfo version;
|
||||
using (connection)
|
||||
{
|
||||
try
|
||||
{
|
||||
connection.Open();
|
||||
var command = connection.CreateCommand();
|
||||
command.CommandText = "SELECT SERVERPROPERTY('ProductVersion');";
|
||||
var productVersion = command.ExecuteScalar().ToString();
|
||||
command.CommandText = sql;
|
||||
using (var reader = command.ExecuteReader())
|
||||
{
|
||||
version = new ServerVersionInfo(reader.GetString(0), reader.GetString(2), reader.GetString(3), (EngineEdition) reader.GetInt32(5), reader.GetString(7), reader.GetString(9));
|
||||
}
|
||||
connection.Close();
|
||||
return MapProductVersion(productVersion);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return VersionName.Unknown;
|
||||
version = new ServerVersionInfo(); // all unknown
|
||||
}
|
||||
}
|
||||
|
||||
return ServerVersion = version;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
{
|
||||
/// <summary>
|
||||
/// Attribute for implementations of an ISqlSyntaxProvider
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class SqlSyntaxProviderAttribute : Attribute
|
||||
{
|
||||
public SqlSyntaxProviderAttribute(string providerName)
|
||||
{
|
||||
ProviderName = providerName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ProviderName that corresponds to the sql syntax in a provider.
|
||||
/// </summary>
|
||||
public string ProviderName { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Data.Common;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using NPoco;
|
||||
using NPoco.FluentMappings;
|
||||
using Umbraco.Core.Exceptions;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Migrations.Install;
|
||||
using Umbraco.Core.Persistence.FaultHandling;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
@@ -27,12 +24,11 @@ namespace Umbraco.Core.Persistence
|
||||
/// </remarks>
|
||||
internal class UmbracoDatabaseFactory : DisposableObject, IUmbracoDatabaseFactory
|
||||
{
|
||||
private readonly ISqlSyntaxProvider[] _sqlSyntaxProviders;
|
||||
private readonly IMapperCollection _mappers;
|
||||
private readonly Lazy<IMapperCollection> _mappers;
|
||||
private readonly ILogger _logger;
|
||||
private readonly SqlContext _sqlContext = new SqlContext();
|
||||
private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
|
||||
|
||||
private SqlContext _sqlContext;
|
||||
private DatabaseFactory _npocoDatabaseFactory;
|
||||
private IPocoDataFactory _pocoDataFactory;
|
||||
private string _connectionString;
|
||||
@@ -51,24 +47,20 @@ namespace Umbraco.Core.Persistence
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UmbracoDatabaseFactory"/>.
|
||||
/// </summary>
|
||||
/// <remarks>Used by injection.</remarks>
|
||||
public UmbracoDatabaseFactory(IEnumerable<ISqlSyntaxProvider> sqlSyntaxProviders, ILogger logger, IMapperCollection mappers)
|
||||
: this(Constants.System.UmbracoConnectionName, sqlSyntaxProviders, logger, mappers)
|
||||
{
|
||||
if (Configured == false)
|
||||
DatabaseBuilder.GiveLegacyAChance(this, logger);
|
||||
}
|
||||
/// <remarks>Used by core runtime.</remarks>
|
||||
public UmbracoDatabaseFactory(ILogger logger, Lazy<IMapperCollection> mappers)
|
||||
: this(Constants.System.UmbracoConnectionName, logger, mappers)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UmbracoDatabaseFactory"/>.
|
||||
/// </summary>
|
||||
/// <remarks>Used by the other ctor and in tests.</remarks>
|
||||
public UmbracoDatabaseFactory(string connectionStringName, IEnumerable<ISqlSyntaxProvider> sqlSyntaxProviders, ILogger logger, IMapperCollection mappers)
|
||||
public UmbracoDatabaseFactory(string connectionStringName, ILogger logger, Lazy<IMapperCollection> mappers)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(connectionStringName)) throw new ArgumentNullOrEmptyException(nameof(connectionStringName));
|
||||
|
||||
_mappers = mappers ?? throw new ArgumentNullException(nameof(mappers));
|
||||
_sqlSyntaxProviders = sqlSyntaxProviders?.ToArray() ?? throw new ArgumentNullException(nameof(sqlSyntaxProviders));
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
var settings = ConfigurationManager.ConnectionStrings[connectionStringName];
|
||||
@@ -92,10 +84,9 @@ namespace Umbraco.Core.Persistence
|
||||
/// Initializes a new instance of the <see cref="UmbracoDatabaseFactory"/>.
|
||||
/// </summary>
|
||||
/// <remarks>Used in tests.</remarks>
|
||||
public UmbracoDatabaseFactory(string connectionString, string providerName, IEnumerable<ISqlSyntaxProvider> sqlSyntaxProviders, ILogger logger, IMapperCollection mappers)
|
||||
public UmbracoDatabaseFactory(string connectionString, string providerName, ILogger logger, Lazy<IMapperCollection> mappers)
|
||||
{
|
||||
_mappers = mappers ?? throw new ArgumentNullException(nameof(mappers));
|
||||
_sqlSyntaxProviders = sqlSyntaxProviders?.ToArray() ?? throw new ArgumentNullException(nameof(sqlSyntaxProviders));
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
if (string.IsNullOrWhiteSpace(connectionString) || string.IsNullOrWhiteSpace(providerName))
|
||||
@@ -139,7 +130,7 @@ namespace Umbraco.Core.Persistence
|
||||
if (setting.IsNullOrWhiteSpace() || !setting.StartsWith("SqlServer.")
|
||||
|| !Enum<SqlServerSyntaxProvider.VersionName>.TryParse(setting.Substring("SqlServer.".Length), out var versionName, true))
|
||||
{
|
||||
versionName = SqlServerSyntaxProvider.GetVersionName(_connectionString, _providerName);
|
||||
versionName = ((SqlServerSyntaxProvider) _sqlSyntax).GetSetVersion(_connectionString, _providerName).ProductVersionName;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -165,7 +156,7 @@ namespace Umbraco.Core.Persistence
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ISqlContext SqlContext => _sqlContext;
|
||||
public ISqlContext SqlContext => _sqlContext ?? (_sqlContext = new SqlContext(_sqlSyntax, _databaseType, _pocoDataFactory, _mappers.Value));
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ConfigureForUpgrade()
|
||||
@@ -218,10 +209,6 @@ namespace Umbraco.Core.Persistence
|
||||
|
||||
if (_npocoDatabaseFactory == null) throw new NullReferenceException("The call to UmbracoDatabaseFactory.Config yielded a null UmbracoDatabaseFactory instance.");
|
||||
|
||||
// can initialize now because it is the UmbracoDatabaseFactory that determines
|
||||
// the sql syntax, poco data factory, and database type
|
||||
_sqlContext.Initialize(_sqlSyntax, _databaseType, _pocoDataFactory, _mappers);
|
||||
|
||||
_logger.Debug<UmbracoDatabaseFactory>("Configured.");
|
||||
Configured = true;
|
||||
}
|
||||
@@ -245,17 +232,17 @@ namespace Umbraco.Core.Persistence
|
||||
// gets the sql syntax provider that corresponds, from attribute
|
||||
private ISqlSyntaxProvider GetSqlSyntaxProvider(string providerName)
|
||||
{
|
||||
var name = providerName.ToLowerInvariant();
|
||||
var provider = _sqlSyntaxProviders.FirstOrDefault(x =>
|
||||
x.GetType()
|
||||
.FirstAttribute<SqlSyntaxProviderAttribute>()
|
||||
.ProviderName.ToLowerInvariant()
|
||||
.Equals(name));
|
||||
if (provider != null) return provider;
|
||||
throw new InvalidOperationException($"Unknown provider name \"{providerName}\"");
|
||||
|
||||
// previously we'd try to return SqlServerSyntaxProvider by default but this is bad
|
||||
//provider = _syntaxProviders.FirstOrDefault(x => x.GetType() == typeof(SqlServerSyntaxProvider));
|
||||
switch (providerName)
|
||||
{
|
||||
case Constants.DbProviderNames.MySql:
|
||||
return new MySqlSyntaxProvider(_logger);
|
||||
case Constants.DbProviderNames.SqlCe:
|
||||
return new SqlCeSyntaxProvider();
|
||||
case Constants.DbProviderNames.SqlServer:
|
||||
return new SqlServerSyntaxProvider();
|
||||
default:
|
||||
throw new InvalidOperationException($"Unknown provider name \"{providerName}\"");
|
||||
}
|
||||
}
|
||||
|
||||
// ensures that the database is configured, else throws
|
||||
@@ -277,7 +264,7 @@ namespace Umbraco.Core.Persistence
|
||||
// method used by NPoco's UmbracoDatabaseFactory to actually create the database instance
|
||||
private UmbracoDatabase CreateDatabaseInstance()
|
||||
{
|
||||
return new UmbracoDatabase(_connectionString, _sqlContext, _dbProviderFactory, _logger, _connectionRetryPolicy, _commandRetryPolicy);
|
||||
return new UmbracoDatabase(_connectionString, SqlContext, _dbProviderFactory, _logger, _connectionRetryPolicy, _commandRetryPolicy);
|
||||
}
|
||||
|
||||
protected override void DisposeResources()
|
||||
|
||||
@@ -4,10 +4,6 @@ namespace Umbraco.Core.PropertyEditors
|
||||
{
|
||||
public class DataEditorCollectionBuilder : LazyCollectionBuilderBase<DataEditorCollectionBuilder, DataEditorCollection, IDataEditor>
|
||||
{
|
||||
public DataEditorCollectionBuilder(IContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
protected override DataEditorCollectionBuilder This => this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,6 @@ namespace Umbraco.Core.PropertyEditors
|
||||
{
|
||||
internal class ManifestValueValidatorCollectionBuilder : LazyCollectionBuilderBase<ManifestValueValidatorCollectionBuilder, ManifestValueValidatorCollection, IManifestValueValidator>
|
||||
{
|
||||
public ManifestValueValidatorCollectionBuilder(IContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
protected override ManifestValueValidatorCollectionBuilder This => this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,6 @@ namespace Umbraco.Core.PropertyEditors
|
||||
{
|
||||
public class PropertyValueConverterCollectionBuilder : OrderedCollectionBuilderBase<PropertyValueConverterCollectionBuilder, PropertyValueConverterCollection, IPropertyValueConverter>
|
||||
{
|
||||
public PropertyValueConverterCollectionBuilder(IContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
protected override PropertyValueConverterCollectionBuilder This => this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,9 @@ using Umbraco.Core.Logging.Serilog;
|
||||
using Umbraco.Core.Migrations.Upgrade;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Scoping;
|
||||
using Umbraco.Core.Services.Implement;
|
||||
using Umbraco.Core.Sync;
|
||||
|
||||
namespace Umbraco.Core.Runtime
|
||||
{
|
||||
@@ -28,39 +28,71 @@ namespace Umbraco.Core.Runtime
|
||||
/// should be possible to use this runtime in console apps.</remarks>
|
||||
public class CoreRuntime : IRuntime
|
||||
{
|
||||
private BootLoader _bootLoader;
|
||||
private Components.Components _components;
|
||||
private RuntimeState _state;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the logger.
|
||||
/// </summary>
|
||||
protected ILogger Logger { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the profiling logger.
|
||||
/// </summary>
|
||||
protected IProfilingLogger ProfilingLogger { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual void Boot(IContainer container)
|
||||
{
|
||||
// assign current container
|
||||
Current.Container = container;
|
||||
|
||||
// register the essential stuff,
|
||||
// ie the global application logger
|
||||
// (profiler etc depend on boot manager)
|
||||
// create and register the essential services
|
||||
// ie the bare minimum required to boot
|
||||
|
||||
var composition = new Composition(container, RuntimeLevel.Boot);
|
||||
|
||||
// loggers
|
||||
var logger = GetLogger();
|
||||
container.RegisterInstance(logger);
|
||||
// now it is ok to use Current.Logger
|
||||
Logger = logger;
|
||||
var profiler = GetProfiler();
|
||||
container.RegisterInstance(profiler);
|
||||
var profilingLogger = new ProfilingLogger(logger, profiler);
|
||||
container.RegisterInstance<IProfilingLogger>(profilingLogger);
|
||||
ProfilingLogger = profilingLogger;
|
||||
|
||||
ConfigureUnhandledException(logger);
|
||||
ConfigureAssemblyResolve(logger);
|
||||
// application environment
|
||||
ConfigureUnhandledException();
|
||||
ConfigureAssemblyResolve();
|
||||
ConfigureApplicationRootPath();
|
||||
|
||||
Compose(container);
|
||||
// application caches
|
||||
var appCaches = GetAppCaches();
|
||||
container.RegisterInstance(appCaches);
|
||||
var runtimeCache = appCaches.RuntimeCache;
|
||||
container.RegisterInstance(runtimeCache);
|
||||
|
||||
// prepare essential stuff
|
||||
// database factory
|
||||
var databaseFactory = new UmbracoDatabaseFactory(logger, new Lazy<IMapperCollection>(container.GetInstance<IMapperCollection>));
|
||||
container.RegisterSingleton(factory => factory.GetInstance<IUmbracoDatabaseFactory>().SqlContext);
|
||||
|
||||
var path = GetApplicationRootPath();
|
||||
if (string.IsNullOrWhiteSpace(path) == false)
|
||||
IOHelper.SetRootDirectory(path);
|
||||
// type loader
|
||||
var globalSettings = UmbracoConfig.For.GlobalSettings();
|
||||
var typeLoader = new TypeLoader(runtimeCache, globalSettings, profilingLogger);
|
||||
container.RegisterInstance(typeLoader);
|
||||
|
||||
_state = (RuntimeState) container.GetInstance<IRuntimeState>();
|
||||
_state.Level = RuntimeLevel.Boot;
|
||||
// runtime state
|
||||
_state = new RuntimeState(logger,
|
||||
UmbracoConfig.For.UmbracoSettings(), UmbracoConfig.For.GlobalSettings(),
|
||||
new Lazy<MainDom>(container.GetInstance<MainDom>),
|
||||
new Lazy<IServerRegistrar>(container.GetInstance<IServerRegistrar>))
|
||||
{
|
||||
Level = RuntimeLevel.Boot
|
||||
};
|
||||
container.RegisterInstance(_state);
|
||||
|
||||
Logger = container.GetInstance<ILogger>();
|
||||
Profiler = container.GetInstance<IProfiler>();
|
||||
ProfilingLogger = container.GetInstance<ProfilingLogger>();
|
||||
Compose(composition);
|
||||
|
||||
// the boot loader boots using a container scope, so anything that is PerScope will
|
||||
// be disposed after the boot loader has booted, and anything else will remain.
|
||||
@@ -76,18 +108,33 @@ namespace Umbraco.Core.Runtime
|
||||
"Booted.",
|
||||
"Boot failed."))
|
||||
{
|
||||
// throws if not full-trust
|
||||
new AspNetHostingPermission(AspNetHostingPermissionLevel.Unrestricted).Demand();
|
||||
|
||||
try
|
||||
{
|
||||
Logger.Debug<CoreRuntime>("Runtime: {Runtime}", GetType().FullName);
|
||||
// throws if not full-trust
|
||||
new AspNetHostingPermission(AspNetHostingPermissionLevel.Unrestricted).Demand();
|
||||
|
||||
AquireMainDom(container);
|
||||
DetermineRuntimeLevel(container);
|
||||
var componentTypes = ResolveComponentTypes();
|
||||
_bootLoader = new BootLoader(container);
|
||||
_bootLoader.Boot(componentTypes, _state.Level);
|
||||
logger.Debug<CoreRuntime>("Runtime: {Runtime}", GetType().FullName);
|
||||
|
||||
var mainDom = AquireMainDom();
|
||||
container.RegisterInstance(mainDom);
|
||||
|
||||
DetermineRuntimeLevel(databaseFactory);
|
||||
|
||||
var componentTypes = ResolveComponentTypes(typeLoader);
|
||||
_components = new Components.Components(composition, componentTypes, profilingLogger);
|
||||
|
||||
_components.Compose();
|
||||
|
||||
// no Current.Container only Current.Factory?
|
||||
//factory = register.Compile();
|
||||
|
||||
// fixme at that point we can start actually getting things from the container
|
||||
// but, ideally, not before = need to detect everything we use!!
|
||||
|
||||
// at that point, getting things from the container is ok
|
||||
// fixme split IRegistry vs IFactory
|
||||
|
||||
_components.Initialize();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -105,15 +152,7 @@ namespace Umbraco.Core.Runtime
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a logger.
|
||||
/// </summary>
|
||||
protected virtual ILogger GetLogger()
|
||||
{
|
||||
return SerilogLogger.CreateWithDefaultConfiguration();
|
||||
}
|
||||
|
||||
protected virtual void ConfigureUnhandledException(ILogger logger)
|
||||
protected virtual void ConfigureUnhandledException()
|
||||
{
|
||||
//take care of unhandled exceptions - there is nothing we can do to
|
||||
// prevent the launch process to go down but at least we can try
|
||||
@@ -126,33 +165,40 @@ namespace Umbraco.Core.Runtime
|
||||
var msg = "Unhandled exception in AppDomain";
|
||||
if (isTerminating) msg += " (terminating)";
|
||||
msg += ".";
|
||||
logger.Error<CoreRuntime>(exception, msg);
|
||||
Logger.Error<CoreRuntime>(exception, msg);
|
||||
};
|
||||
}
|
||||
|
||||
protected virtual void ConfigureAssemblyResolve(ILogger logger)
|
||||
protected virtual void ConfigureAssemblyResolve()
|
||||
{
|
||||
// When an assembly can't be resolved. In here we can do magic with the assembly name and try loading another.
|
||||
// This is used for loading a signed assembly of AutoMapper (v. 3.1+) without having to recompile old code.
|
||||
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
|
||||
{
|
||||
// ensure the assembly is indeed AutoMapper and that the PublicKeyToken is null before trying to Load again
|
||||
// do NOT just replace this with 'return Assembly', as it will cause an infinite loop -> stackoverflow
|
||||
// do NOT just replace this with 'return Assembly', as it will cause an infinite loop -> stack overflow
|
||||
if (args.Name.StartsWith("AutoMapper") && args.Name.EndsWith("PublicKeyToken=null"))
|
||||
return Assembly.Load(args.Name.Replace(", PublicKeyToken=null", ", PublicKeyToken=be96cd2c38ef1005"));
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private void AquireMainDom(IContainer container)
|
||||
protected virtual void ConfigureApplicationRootPath()
|
||||
{
|
||||
using (var timer = ProfilingLogger.DebugDuration<CoreRuntime>("Acquiring MainDom.", "Aquired."))
|
||||
var path = GetApplicationRootPath();
|
||||
if (string.IsNullOrWhiteSpace(path) == false)
|
||||
IOHelper.SetRootDirectory(path);
|
||||
}
|
||||
|
||||
private MainDom AquireMainDom()
|
||||
{
|
||||
using (var timer = ProfilingLogger.DebugDuration<CoreRuntime>("Acquiring MainDom.", "Acquired."))
|
||||
{
|
||||
try
|
||||
{
|
||||
var mainDom = container.GetInstance<MainDom>();
|
||||
var mainDom = new MainDom(Logger);
|
||||
mainDom.Acquire();
|
||||
return mainDom;
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -163,38 +209,38 @@ namespace Umbraco.Core.Runtime
|
||||
}
|
||||
|
||||
// internal for tests
|
||||
internal void DetermineRuntimeLevel(IContainer container)
|
||||
internal void DetermineRuntimeLevel(IUmbracoDatabaseFactory databaseFactory)
|
||||
{
|
||||
using (var timer = ProfilingLogger.DebugDuration<CoreRuntime>("Determining runtime level.", "Determined."))
|
||||
{
|
||||
try
|
||||
{
|
||||
var dbfactory = container.GetInstance<IUmbracoDatabaseFactory>();
|
||||
SetRuntimeStateLevel(dbfactory, Logger);
|
||||
_state.Level = DetermineRuntimeLevel2(databaseFactory);
|
||||
|
||||
Logger.Debug<CoreRuntime>("Runtime level: {RuntimeLevel}", _state.Level);
|
||||
ProfilingLogger.Debug<CoreRuntime>("Runtime level: {RuntimeLevel}", _state.Level);
|
||||
|
||||
if (_state.Level == RuntimeLevel.Upgrade)
|
||||
{
|
||||
Logger.Debug<CoreRuntime>("Configure database factory for upgrades.");
|
||||
dbfactory.ConfigureForUpgrade();
|
||||
ProfilingLogger.Debug<CoreRuntime>("Configure database factory for upgrades.");
|
||||
databaseFactory.ConfigureForUpgrade();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_state.Level = RuntimeLevel.BootFailed;
|
||||
timer.Fail();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<Type> ResolveComponentTypes()
|
||||
private IEnumerable<Type> ResolveComponentTypes(TypeLoader typeLoader)
|
||||
{
|
||||
using (var timer = ProfilingLogger.TraceDuration<CoreRuntime>("Resolving component types.", "Resolved."))
|
||||
{
|
||||
try
|
||||
{
|
||||
return GetComponentTypes();
|
||||
return GetComponentTypes(typeLoader);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -209,97 +255,56 @@ namespace Umbraco.Core.Runtime
|
||||
{
|
||||
using (ProfilingLogger.DebugDuration<CoreRuntime>("Terminating Umbraco.", "Terminated."))
|
||||
{
|
||||
_bootLoader?.Terminate();
|
||||
_components?.Terminate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Composes the runtime.
|
||||
/// </summary>
|
||||
public virtual void Compose(IContainer container)
|
||||
public virtual void Compose(Composition composition)
|
||||
{
|
||||
var container = composition.Container;
|
||||
|
||||
// compose the very essential things that are needed to bootstrap, before anything else,
|
||||
// and only these things - the rest should be composed in runtime components
|
||||
|
||||
// register basic things
|
||||
container.RegisterSingleton<IProfiler, LogProfiler>();
|
||||
container.RegisterSingleton<ProfilingLogger>();
|
||||
container.RegisterSingleton<IRuntimeState, RuntimeState>();
|
||||
// FIXME should be essentially empty! move all to component!
|
||||
|
||||
container.ComposeConfiguration();
|
||||
|
||||
// register caches
|
||||
// need the deep clone runtime cache profiver to ensure entities are cached properly, ie
|
||||
// are cloned in and cloned out - no request-based cache here since no web-based context,
|
||||
// will be overriden later or
|
||||
container.RegisterSingleton(_ => new CacheHelper(
|
||||
new DeepCloneRuntimeCacheProvider(new ObjectCacheRuntimeCacheProvider()),
|
||||
new StaticCacheProvider(),
|
||||
NullCacheProvider.Instance,
|
||||
new IsolatedRuntimeCache(type => new DeepCloneRuntimeCacheProvider(new ObjectCacheRuntimeCacheProvider()))));
|
||||
container.RegisterSingleton(f => f.GetInstance<CacheHelper>().RuntimeCache);
|
||||
|
||||
// register the plugin manager
|
||||
container.RegisterSingleton(f => new TypeLoader(f.GetInstance<IRuntimeCacheProvider>(), f.GetInstance<IGlobalSettings>(), f.GetInstance<ProfilingLogger>()));
|
||||
|
||||
// register syntax providers - required by database factory - GetAllInstances<ISqlSyntaxProvider> or an IEnumerable can get them
|
||||
container.Register<MySqlSyntaxProvider>();
|
||||
container.Register<SqlCeSyntaxProvider>();
|
||||
container.Register<SqlServerSyntaxProvider>();
|
||||
|
||||
// register persistence mappers - required by database factory so needs to be done here
|
||||
// means the only place the collection can be modified is in a runtime - afterwards it
|
||||
// has been frozen and it is too late
|
||||
var mapperCollectionBuilder = container.RegisterCollectionBuilder<MapperCollectionBuilder>();
|
||||
ComposeMapperCollection(mapperCollectionBuilder);
|
||||
|
||||
// register database factory - required to check for migrations
|
||||
// will be initialized with syntax providers and a logger, and will try to configure
|
||||
// from the default connection string name, if possible, else will remain non-configured
|
||||
// until properly configured (eg when installing)
|
||||
container.RegisterSingleton<IUmbracoDatabaseFactory, UmbracoDatabaseFactory>();
|
||||
container.RegisterSingleton(f => f.GetInstance<IUmbracoDatabaseFactory>().SqlContext);
|
||||
composition.GetCollectionBuilder<MapperCollectionBuilder>().AddCoreMappers();
|
||||
|
||||
// register the scope provider
|
||||
container.RegisterSingleton<ScopeProvider>(); // implements both IScopeProvider and IScopeAccessor
|
||||
container.RegisterSingleton<IScopeProvider>(f => f.GetInstance<ScopeProvider>());
|
||||
container.RegisterSingleton<IScopeAccessor>(f => f.GetInstance<ScopeProvider>());
|
||||
|
||||
// register MainDom
|
||||
container.RegisterSingleton<MainDom>();
|
||||
}
|
||||
|
||||
protected virtual void ComposeMapperCollection(MapperCollectionBuilder builder)
|
||||
{
|
||||
builder.AddCore();
|
||||
}
|
||||
|
||||
private void SetRuntimeStateLevel(IUmbracoDatabaseFactory databaseFactory, ILogger logger)
|
||||
private RuntimeLevel DetermineRuntimeLevel2(IUmbracoDatabaseFactory databaseFactory)
|
||||
{
|
||||
var localVersion = UmbracoVersion.LocalVersion; // the local, files, version
|
||||
var codeVersion = _state.SemanticVersion; // the executing code version
|
||||
var connect = false;
|
||||
|
||||
// we don't know yet
|
||||
_state.Level = RuntimeLevel.Unknown;
|
||||
|
||||
if (localVersion == null)
|
||||
{
|
||||
// there is no local version, we are not installed
|
||||
logger.Debug<CoreRuntime>("No local version, need to install Umbraco.");
|
||||
_state.Level = RuntimeLevel.Install;
|
||||
Logger.Debug<CoreRuntime>("No local version, need to install Umbraco.");
|
||||
return RuntimeLevel.Install;
|
||||
}
|
||||
else if (localVersion < codeVersion)
|
||||
|
||||
if (localVersion < codeVersion)
|
||||
{
|
||||
// there *is* a local version, but it does not match the code version
|
||||
// need to upgrade
|
||||
logger.Debug<CoreRuntime>("Local version '{LocalVersion}' < code version '{CodeVersion}', need to upgrade Umbraco.", localVersion, codeVersion);
|
||||
_state.Level = RuntimeLevel.Upgrade;
|
||||
Logger.Debug<CoreRuntime>("Local version '{LocalVersion}' < code version '{CodeVersion}', need to upgrade Umbraco.", localVersion, codeVersion);
|
||||
}
|
||||
else if (localVersion > codeVersion)
|
||||
{
|
||||
logger.Warn<CoreRuntime>("Local version '{LocalVersion}' > code version '{CodeVersion}', downgrading is not supported.", localVersion, codeVersion);
|
||||
_state.Level = RuntimeLevel.BootFailed;
|
||||
Logger.Warn<CoreRuntime>("Local version '{LocalVersion}' > code version '{CodeVersion}', downgrading is not supported.", localVersion, codeVersion);
|
||||
|
||||
// in fact, this is bad enough that we want to throw
|
||||
throw new BootFailedException($"Local version \"{localVersion}\" > code version \"{codeVersion}\", downgrading is not supported.");
|
||||
@@ -308,14 +313,10 @@ namespace Umbraco.Core.Runtime
|
||||
{
|
||||
// local version *does* match code version, but the database is not configured
|
||||
// install (again? this is a weird situation...)
|
||||
logger.Debug<CoreRuntime>("Database is not configured, need to install Umbraco.");
|
||||
_state.Level = RuntimeLevel.Install;
|
||||
Logger.Debug<CoreRuntime>("Database is not configured, need to install Umbraco.");
|
||||
return RuntimeLevel.Install;
|
||||
}
|
||||
|
||||
// install? not going to test anything else
|
||||
if (_state.Level == RuntimeLevel.Install)
|
||||
return;
|
||||
|
||||
// else, keep going,
|
||||
// anything other than install wants a database - see if we can connect
|
||||
// (since this is an already existing database, assume localdb is ready)
|
||||
@@ -323,15 +324,14 @@ namespace Umbraco.Core.Runtime
|
||||
{
|
||||
connect = databaseFactory.CanConnect;
|
||||
if (connect) break;
|
||||
logger.Debug<CoreRuntime>("Could not immediately connect to database, trying again.");
|
||||
Logger.Debug<CoreRuntime>("Could not immediately connect to database, trying again.");
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
|
||||
if (connect == false)
|
||||
{
|
||||
// cannot connect to configured database, this is bad, fail
|
||||
logger.Debug<CoreRuntime>("Could not connect to database.");
|
||||
_state.Level = RuntimeLevel.BootFailed;
|
||||
Logger.Debug<CoreRuntime>("Could not connect to database.");
|
||||
|
||||
// in fact, this is bad enough that we want to throw
|
||||
throw new BootFailedException("A connection string is configured but Umbraco could not connect to the database.");
|
||||
@@ -347,20 +347,19 @@ namespace Umbraco.Core.Runtime
|
||||
bool noUpgrade;
|
||||
try
|
||||
{
|
||||
noUpgrade = EnsureUmbracoUpgradeState(databaseFactory, logger);
|
||||
noUpgrade = EnsureUmbracoUpgradeState(databaseFactory);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// can connect to the database but cannot check the upgrade state... oops
|
||||
logger.Warn<CoreRuntime>(e, "Could not check the upgrade state.");
|
||||
Logger.Warn<CoreRuntime>(e, "Could not check the upgrade state.");
|
||||
throw new BootFailedException("Could not check the upgrade state.", e);
|
||||
}
|
||||
|
||||
if (noUpgrade)
|
||||
{
|
||||
// the database version matches the code & files version, all clear, can run
|
||||
_state.Level = RuntimeLevel.Run;
|
||||
return;
|
||||
return RuntimeLevel.Run;
|
||||
}
|
||||
|
||||
// the db version does not match... but we do have a migration table
|
||||
@@ -368,11 +367,11 @@ namespace Umbraco.Core.Runtime
|
||||
|
||||
// although the files version matches the code version, the database version does not
|
||||
// which means the local files have been upgraded but not the database - need to upgrade
|
||||
logger.Debug<CoreRuntime>("Has not reached the final upgrade step, need to upgrade Umbraco.");
|
||||
_state.Level = RuntimeLevel.Upgrade;
|
||||
Logger.Debug<CoreRuntime>("Has not reached the final upgrade step, need to upgrade Umbraco.");
|
||||
return RuntimeLevel.Upgrade;
|
||||
}
|
||||
|
||||
protected virtual bool EnsureUmbracoUpgradeState(IUmbracoDatabaseFactory databaseFactory, ILogger logger)
|
||||
protected virtual bool EnsureUmbracoUpgradeState(IUmbracoDatabaseFactory databaseFactory)
|
||||
{
|
||||
var umbracoPlan = new UmbracoPlan();
|
||||
var stateValueKey = Upgrader.GetStateValueKey(umbracoPlan);
|
||||
@@ -384,31 +383,53 @@ namespace Umbraco.Core.Runtime
|
||||
_state.FinalMigrationState = umbracoPlan.FinalState;
|
||||
}
|
||||
|
||||
logger.Debug<CoreRuntime>("Final upgrade state is {FinalMigrationState}, database contains {DatabaseState}", _state.FinalMigrationState, _state.CurrentMigrationState ?? "<null>");
|
||||
Logger.Debug<CoreRuntime>("Final upgrade state is {FinalMigrationState}, database contains {DatabaseState}", _state.FinalMigrationState, _state.CurrentMigrationState ?? "<null>");
|
||||
|
||||
return _state.CurrentMigrationState == _state.FinalMigrationState;
|
||||
}
|
||||
|
||||
#region Locals
|
||||
|
||||
protected ILogger Logger { get; private set; }
|
||||
|
||||
protected IProfiler Profiler { get; private set; }
|
||||
|
||||
protected ProfilingLogger ProfilingLogger { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Getters
|
||||
|
||||
// getters can be implemented by runtimes inheriting from CoreRuntime
|
||||
|
||||
// fixme - inject! no Current!
|
||||
protected virtual IEnumerable<Type> GetComponentTypes() => Current.TypeLoader.GetTypes<IUmbracoComponent>();
|
||||
/// <summary>
|
||||
/// Gets all component types.
|
||||
/// </summary>
|
||||
protected virtual IEnumerable<Type> GetComponentTypes(TypeLoader typeLoader)
|
||||
=> typeLoader.GetTypes<IUmbracoComponent>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a logger.
|
||||
/// </summary>
|
||||
protected virtual ILogger GetLogger()
|
||||
=> SerilogLogger.CreateWithDefaultConfiguration();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a profiler.
|
||||
/// </summary>
|
||||
protected virtual IProfiler GetProfiler()
|
||||
=> new LogProfiler(ProfilingLogger);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the application caches.
|
||||
/// </summary>
|
||||
protected virtual CacheHelper GetAppCaches()
|
||||
{
|
||||
// need the deep clone runtime cache provider to ensure entities are cached properly, ie
|
||||
// are cloned in and cloned out - no request-based cache here since no web-based context,
|
||||
// is overriden by the web runtime
|
||||
|
||||
return new CacheHelper(
|
||||
new DeepCloneRuntimeCacheProvider(new ObjectCacheRuntimeCacheProvider()),
|
||||
new StaticCacheProvider(),
|
||||
NullCacheProvider.Instance,
|
||||
new IsolatedRuntimeCache(type => new DeepCloneRuntimeCacheProvider(new ObjectCacheRuntimeCacheProvider())));
|
||||
}
|
||||
|
||||
// by default, returns null, meaning that Umbraco should auto-detect the application root path.
|
||||
// override and return the absolute path to the Umbraco site/solution, if needed
|
||||
protected virtual string GetApplicationRootPath() => null;
|
||||
protected virtual string GetApplicationRootPath()
|
||||
=> null;
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace Umbraco.Core.Runtime
|
||||
composition.Container.RegisterSingleton<ManifestParser>();
|
||||
|
||||
// register our predefined validators
|
||||
composition.Container.RegisterCollectionBuilder<ManifestValueValidatorCollectionBuilder>()
|
||||
composition.GetCollectionBuilder<ManifestValueValidatorCollectionBuilder>()
|
||||
.Add<RequiredValidator>()
|
||||
.Add<RegexValidator>()
|
||||
.Add<DelimitedValueValidator>()
|
||||
@@ -56,7 +56,7 @@ namespace Umbraco.Core.Runtime
|
||||
.Add<DecimalValidator>();
|
||||
|
||||
// properties and parameters derive from data editors
|
||||
composition.Container.RegisterCollectionBuilder<DataEditorCollectionBuilder>()
|
||||
composition.GetCollectionBuilder<DataEditorCollectionBuilder>()
|
||||
.Add(factory => factory.GetInstance<TypeLoader>().GetDataEditors());
|
||||
composition.Container.RegisterSingleton<PropertyEditorCollection>();
|
||||
composition.Container.RegisterSingleton<ParameterEditorCollection>();
|
||||
@@ -83,13 +83,13 @@ namespace Umbraco.Core.Runtime
|
||||
factory.GetInstance<IGlobalSettings>(),
|
||||
true, new DatabaseServerMessengerOptions()));
|
||||
|
||||
composition.Container.RegisterCollectionBuilder<CacheRefresherCollectionBuilder>()
|
||||
composition.GetCollectionBuilder<CacheRefresherCollectionBuilder>()
|
||||
.Add(factory => factory.GetInstance<TypeLoader>().GetCacheRefreshers());
|
||||
|
||||
composition.Container.RegisterCollectionBuilder<PackageActionCollectionBuilder>()
|
||||
composition.GetCollectionBuilder<PackageActionCollectionBuilder>()
|
||||
.Add(f => f.GetInstance<TypeLoader>().GetPackageActions());
|
||||
|
||||
composition.Container.RegisterCollectionBuilder<PropertyValueConverterCollectionBuilder>()
|
||||
composition.GetCollectionBuilder<PropertyValueConverterCollectionBuilder>()
|
||||
.Append(factory => factory.GetInstance<TypeLoader>().GetTypes<IPropertyValueConverter>());
|
||||
|
||||
composition.Container.RegisterSingleton<IPublishedContentTypeFactory, PublishedContentTypeFactory>();
|
||||
@@ -97,10 +97,10 @@ namespace Umbraco.Core.Runtime
|
||||
composition.Container.RegisterSingleton<IShortStringHelper>(factory
|
||||
=> new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(factory.GetInstance<IUmbracoSettingsSection>())));
|
||||
|
||||
composition.Container.RegisterCollectionBuilder<UrlSegmentProviderCollectionBuilder>()
|
||||
composition.GetCollectionBuilder<UrlSegmentProviderCollectionBuilder>()
|
||||
.Append<DefaultUrlSegmentProvider>();
|
||||
|
||||
composition.Container.RegisterCollectionBuilder<PostMigrationCollectionBuilder>()
|
||||
composition.GetCollectionBuilder<PostMigrationCollectionBuilder>()
|
||||
.Add(factory => factory.GetInstance<TypeLoader>().GetTypes<IPostMigration>());
|
||||
|
||||
composition.Container.RegisterSingleton<IMigrationBuilder>(factory => new MigrationBuilder(composition.Container));
|
||||
|
||||
@@ -17,76 +17,67 @@ namespace Umbraco.Core
|
||||
internal class RuntimeState : IRuntimeState
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly Lazy<IServerRegistrar> _serverRegistrar;
|
||||
private readonly Lazy<MainDom> _mainDom;
|
||||
private readonly IUmbracoSettingsSection _settings;
|
||||
private readonly IGlobalSettings _globalSettings;
|
||||
private readonly HashSet<string> _applicationUrls = new HashSet<string>();
|
||||
private RuntimeLevel _level;
|
||||
private Lazy<MainDom> _mainDom;
|
||||
private Lazy<IServerRegistrar> _serverRegistrar;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RuntimeState"/> class.
|
||||
/// </summary>
|
||||
/// <param name="logger">A logger.</param>
|
||||
/// <param name="serverRegistrar">A (lazy) server registrar.</param>
|
||||
/// <param name="mainDom">A (lazy) MainDom.</param>
|
||||
public RuntimeState(ILogger logger, Lazy<IServerRegistrar> serverRegistrar, Lazy<MainDom> mainDom, IUmbracoSettingsSection settings, IGlobalSettings globalSettings)
|
||||
/// <param name="settings">Umbraco settings.</param>
|
||||
/// <param name="globalSettings">Global settings.</param>
|
||||
public RuntimeState(ILogger logger, IUmbracoSettingsSection settings, IGlobalSettings globalSettings,
|
||||
Lazy<MainDom> mainDom, Lazy<IServerRegistrar> serverRegistrar)
|
||||
{
|
||||
_logger = logger;
|
||||
_serverRegistrar = serverRegistrar;
|
||||
_mainDom = mainDom;
|
||||
_settings = settings;
|
||||
_globalSettings = globalSettings;
|
||||
_mainDom = mainDom;
|
||||
_serverRegistrar = serverRegistrar;
|
||||
}
|
||||
|
||||
/// <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>This is NOT exposed in the interface as MainDom is internal.</remarks>
|
||||
/// <remarks>
|
||||
/// <para>This is NOT exposed in the interface as MainDom is internal.</para>
|
||||
/// </remarks>
|
||||
public MainDom MainDom => _mainDom.Value;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the version of the executing code.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public Version Version => UmbracoVersion.Current;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the version comment of the executing code.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public string VersionComment => UmbracoVersion.Comment;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the semantic version of the executing code.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public SemVersion SemanticVersion => UmbracoVersion.SemanticVersion;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the application is running in debug mode.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public bool Debug { get; } = GlobalSettings.DebugMode;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the runtime is the current main domain.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public bool IsMainDom => MainDom.IsMainDom;
|
||||
|
||||
/// <summary>
|
||||
/// Get the server's current role.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public ServerRole ServerRole => ServerRegistrar.GetCurrentServerRole();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Umbraco application url.
|
||||
/// </summary>
|
||||
/// <remarks>This is eg "http://www.example.com".</remarks>
|
||||
/// <inheritdoc />
|
||||
public Uri ApplicationUrl { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Umbraco application virtual path.
|
||||
/// </summary>
|
||||
/// <remarks>This is either "/" or eg "/virtual".</remarks>
|
||||
/// <inheritdoc />
|
||||
public string ApplicationVirtualPath { get; } = HttpRuntime.AppDomainAppVirtualPath;
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -95,9 +86,7 @@ namespace Umbraco.Core
|
||||
/// <inheritdoc />
|
||||
public string FinalMigrationState { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the runtime level of execution.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public RuntimeLevel Level
|
||||
{
|
||||
get => _level;
|
||||
@@ -137,9 +126,7 @@ namespace Umbraco.Core
|
||||
return _runLevel.WaitHandle.WaitOne(timeout);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the exception that caused the boot to fail.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public BootFailedException BootFailedException { get; internal set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,6 @@ namespace Umbraco.Core.Strings
|
||||
{
|
||||
public class UrlSegmentProviderCollectionBuilder : OrderedCollectionBuilderBase<UrlSegmentProviderCollectionBuilder, UrlSegmentProviderCollection, IUrlSegmentProvider>
|
||||
{
|
||||
public UrlSegmentProviderCollectionBuilder(IContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
protected override UrlSegmentProviderCollectionBuilder This => this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@
|
||||
<Compile Include="Collections\ListCloneBehavior.cs" />
|
||||
<Compile Include="Collections\ObservableDictionary.cs" />
|
||||
<Compile Include="Collections\TypeList.cs" />
|
||||
<Compile Include="Components\BootLoader.cs" />
|
||||
<Compile Include="Components\Components.cs" />
|
||||
<Compile Include="Components\Composition.cs" />
|
||||
<Compile Include="Components\CompositionExtensions.cs" />
|
||||
<Compile Include="Components\DisableComponentAttribute.cs" />
|
||||
@@ -335,6 +335,7 @@
|
||||
<Compile Include="IO\MediaPathSchemes\OriginalMediaPathScheme.cs" />
|
||||
<Compile Include="IO\MediaPathSchemes\TwoGuidsMediaPathScheme.cs" />
|
||||
<Compile Include="KeyValuePairExtensions.cs" />
|
||||
<Compile Include="Logging\IProfilingLogger.cs" />
|
||||
<Compile Include="Logging\LogHttpRequest.cs" />
|
||||
<Compile Include="Logging\LogLevel.cs" />
|
||||
<Compile Include="Logging\MessageTemplates.cs" />
|
||||
@@ -1222,7 +1223,6 @@
|
||||
<Compile Include="Persistence\SqlSyntax\SqlCeSyntaxProvider.cs" />
|
||||
<Compile Include="Persistence\SqlSyntax\SqlServerSyntaxProvider.cs" />
|
||||
<Compile Include="Persistence\SqlSyntax\SqlServerVersionName.cs" />
|
||||
<Compile Include="Persistence\SqlSyntax\SqlSyntaxProviderAttribute.cs" />
|
||||
<Compile Include="Persistence\SqlSyntax\SqlSyntaxProviderBase.cs" />
|
||||
<Compile Include="Persistence\SqlSyntax\SqlSyntaxProviderExtensions.cs" />
|
||||
<Compile Include="Persistence\SqlTemplate.cs" />
|
||||
|
||||
@@ -4,10 +4,6 @@ namespace Umbraco.Core._Legacy.PackageActions
|
||||
{
|
||||
internal class PackageActionCollectionBuilder : LazyCollectionBuilderBase<PackageActionCollectionBuilder, PackageActionCollection, IPackageAction>
|
||||
{
|
||||
public PackageActionCollectionBuilder(IContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
protected override PackageActionCollectionBuilder This => this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,18 +4,12 @@ using System.Data.SqlServerCe;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using BenchmarkDotNet.Configs;
|
||||
using BenchmarkDotNet.Diagnosers;
|
||||
using BenchmarkDotNet.Horology;
|
||||
using BenchmarkDotNet.Jobs;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Migrations.Install;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Scoping;
|
||||
using Umbraco.Tests.Benchmarks.Config;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
@@ -34,13 +28,11 @@ namespace Umbraco.Tests.Benchmarks
|
||||
{
|
||||
IScopeProvider f = null;
|
||||
var l = new Lazy<IScopeProvider>(() => f);
|
||||
var p = new SqlServerSyntaxProvider(l);
|
||||
var factory = new UmbracoDatabaseFactory(
|
||||
"server=.\\SQLExpress;database=YOURDB;user id=YOURUSER;password=YOURPASS",
|
||||
Constants.DatabaseProviders.SqlServer,
|
||||
new [] { p },
|
||||
logger,
|
||||
new MapperCollection(Enumerable.Empty<BaseMapper>()));
|
||||
new Lazy<IMapperCollection>(() => new MapperCollection(Enumerable.Empty<BaseMapper>())));
|
||||
return factory.CreateDatabase();
|
||||
}
|
||||
|
||||
@@ -49,9 +41,8 @@ namespace Umbraco.Tests.Benchmarks
|
||||
var f = new UmbracoDatabaseFactory(
|
||||
cstr,
|
||||
Constants.DatabaseProviders.SqlCe,
|
||||
new[] { new SqlCeSyntaxProvider() },
|
||||
logger,
|
||||
new MapperCollection(Enumerable.Empty<BaseMapper>()));
|
||||
new Lazy<IMapperCollection>(() => new MapperCollection(Enumerable.Empty<BaseMapper>())));
|
||||
return f.CreateDatabase();
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Components;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Sync;
|
||||
|
||||
@@ -21,11 +22,12 @@ namespace Umbraco.Tests.Cache.DistributedCache
|
||||
public void Setup()
|
||||
{
|
||||
var container = Current.Container = ContainerFactory.Create();
|
||||
var composition = new Composition(container, RuntimeLevel.Run);
|
||||
|
||||
container.Register<IServerRegistrar>(_ => new TestServerRegistrar());
|
||||
container.RegisterSingleton<IServerMessenger>(_ => new TestServerMessenger());
|
||||
|
||||
container.RegisterCollectionBuilder<CacheRefresherCollectionBuilder>()
|
||||
composition.GetCollectionBuilder<CacheRefresherCollectionBuilder>()
|
||||
.Add<TestCacheRefresher>();
|
||||
|
||||
_distributedCache = new Umbraco.Web.Cache.DistributedCache();
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Umbraco.Tests.Cache.PublishedCache
|
||||
{
|
||||
base.Compose();
|
||||
|
||||
Container.GetInstance<UrlSegmentProviderCollectionBuilder>()
|
||||
Composition.GetCollectionBuilder<UrlSegmentProviderCollectionBuilder>()
|
||||
.Clear()
|
||||
.Append<DefaultUrlSegmentProvider>();
|
||||
}
|
||||
|
||||
@@ -27,10 +27,8 @@ namespace Umbraco.Tests.Components
|
||||
|
||||
var mock = new Mock<IContainer>();
|
||||
|
||||
var testObjects = new TestObjects(null);
|
||||
var logger = Mock.Of<ILogger>();
|
||||
var s = testObjects.GetDefaultSqlSyntaxProviders(logger);
|
||||
var f = new UmbracoDatabaseFactory(s, logger, new MapperCollection(Enumerable.Empty<BaseMapper>()));
|
||||
var f = new UmbracoDatabaseFactory(logger, new Lazy<IMapperCollection>(() => new MapperCollection(Enumerable.Empty<BaseMapper>())));
|
||||
var fs = new FileSystems(mock.Object, logger);
|
||||
var p = new ScopeProvider(f, fs, logger);
|
||||
|
||||
@@ -47,13 +45,15 @@ namespace Umbraco.Tests.Components
|
||||
public void Boot1A()
|
||||
{
|
||||
var container = MockContainer();
|
||||
var composition = new Composition(container, RuntimeLevel.Unknown);
|
||||
|
||||
var loader = new BootLoader(container);
|
||||
var types = TypeArray<Component1, Component2, Component3, Component4>();
|
||||
var components = new Core.Components.Components(composition, types, Mock.Of<IProfilingLogger>());
|
||||
Composed.Clear();
|
||||
// 2 is Core and requires 4
|
||||
// 3 is User - goes away with RuntimeLevel.Unknown
|
||||
// => reorder components accordingly
|
||||
loader.Boot(TypeArray<Component1, Component2, Component3, Component4>(), RuntimeLevel.Unknown);
|
||||
components.Compose();
|
||||
AssertTypeArray(TypeArray<Component1, Component4, Component2>(), Composed);
|
||||
}
|
||||
|
||||
@@ -61,13 +61,15 @@ namespace Umbraco.Tests.Components
|
||||
public void Boot1B()
|
||||
{
|
||||
var container = MockContainer();
|
||||
var composition = new Composition(container, RuntimeLevel.Run);
|
||||
|
||||
var loader = new BootLoader(container);
|
||||
var types = TypeArray<Component1, Component2, Component3, Component4>();
|
||||
var components = new Core.Components.Components(composition, types, Mock.Of<IProfilingLogger>());
|
||||
Composed.Clear();
|
||||
// 2 is Core and requires 4
|
||||
// 3 is User - stays with RuntimeLevel.Run
|
||||
// => reorder components accordingly
|
||||
loader.Boot(TypeArray<Component1, Component2, Component3, Component4>(), RuntimeLevel.Run);
|
||||
components.Compose();
|
||||
AssertTypeArray(TypeArray<Component1, Component4, Component2, Component3>(), Composed);
|
||||
}
|
||||
|
||||
@@ -75,12 +77,14 @@ namespace Umbraco.Tests.Components
|
||||
public void Boot2()
|
||||
{
|
||||
var container = MockContainer();
|
||||
var composition = new Composition(container, RuntimeLevel.Unknown);
|
||||
|
||||
var loader = new BootLoader(container);
|
||||
var types = TypeArray<Component20, Component21>();
|
||||
var components = new Core.Components.Components(composition, types, Mock.Of<IProfilingLogger>());
|
||||
Composed.Clear();
|
||||
// 21 is required by 20
|
||||
// => reorder components accordingly
|
||||
loader.Boot(TypeArray<Component20, Component21>(), RuntimeLevel.Unknown);
|
||||
components.Compose();
|
||||
AssertTypeArray(TypeArray<Component21, Component20>(), Composed);
|
||||
}
|
||||
|
||||
@@ -88,14 +92,16 @@ namespace Umbraco.Tests.Components
|
||||
public void Boot3()
|
||||
{
|
||||
var container = MockContainer();
|
||||
var composition = new Composition(container, RuntimeLevel.Unknown);
|
||||
|
||||
var loader = new BootLoader(container);
|
||||
var types = TypeArray<Component22, Component24, Component25>();
|
||||
var components = new Core.Components.Components(composition, types, Mock.Of<IProfilingLogger>());
|
||||
Composed.Clear();
|
||||
// i23 requires 22
|
||||
// 24, 25 implement i23
|
||||
// 25 required by i23
|
||||
// => reorder components accordingly
|
||||
loader.Boot(TypeArray<Component22, Component24, Component25>(), RuntimeLevel.Unknown);
|
||||
components.Compose();
|
||||
AssertTypeArray(TypeArray<Component22, Component25, Component24>(), Composed);
|
||||
}
|
||||
|
||||
@@ -103,15 +109,17 @@ namespace Umbraco.Tests.Components
|
||||
public void BrokenRequire()
|
||||
{
|
||||
var container = MockContainer();
|
||||
var composition = new Composition(container, RuntimeLevel.Unknown);
|
||||
|
||||
var thing = new BootLoader(container);
|
||||
var types = TypeArray<Component1, Component2, Component3>();
|
||||
var components = new Core.Components.Components(composition, types, Mock.Of<IProfilingLogger>());
|
||||
Composed.Clear();
|
||||
try
|
||||
{
|
||||
// 2 is Core and requires 4
|
||||
// 4 is missing
|
||||
// => throw
|
||||
thing.Boot(TypeArray < Component1, Component2, Component3>(), RuntimeLevel.Unknown);
|
||||
components.Compose();
|
||||
Assert.Fail("Expected exception.");
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -124,14 +132,16 @@ namespace Umbraco.Tests.Components
|
||||
public void BrokenRequired()
|
||||
{
|
||||
var container = MockContainer();
|
||||
var composition = new Composition(container, RuntimeLevel.Unknown);
|
||||
|
||||
var thing = new BootLoader(container);
|
||||
var types = TypeArray<Component2, Component4, Component13>();
|
||||
var components = new Core.Components.Components(composition, types, Mock.Of<IProfilingLogger>());
|
||||
Composed.Clear();
|
||||
// 2 is Core and requires 4
|
||||
// 13 is required by 1
|
||||
// 1 is missing
|
||||
// => reorder components accordingly
|
||||
thing.Boot(TypeArray<Component2, Component4, Component13>(), RuntimeLevel.Unknown);
|
||||
components.Compose();
|
||||
AssertTypeArray(TypeArray<Component4, Component2, Component13>(), Composed);
|
||||
}
|
||||
|
||||
@@ -142,11 +152,14 @@ namespace Umbraco.Tests.Components
|
||||
{
|
||||
m.Setup(x => x.TryGetInstance(It.Is<Type>(t => t == typeof (ISomeResource)))).Returns(() => new SomeResource());
|
||||
});
|
||||
var composition = new Composition(container, RuntimeLevel.Unknown);
|
||||
|
||||
var thing = new BootLoader(container);
|
||||
var types = new[] { typeof(Component1), typeof(Component5) };
|
||||
var components = new Core.Components.Components(composition, types, Mock.Of<IProfilingLogger>());
|
||||
Composed.Clear();
|
||||
Initialized.Clear();
|
||||
thing.Boot(new[] { typeof(Component1), typeof(Component5) }, RuntimeLevel.Unknown);
|
||||
components.Compose();
|
||||
components.Initialize();
|
||||
Assert.AreEqual(2, Composed.Count);
|
||||
Assert.AreEqual(typeof(Component1), Composed[0]);
|
||||
Assert.AreEqual(typeof(Component5), Composed[1]);
|
||||
@@ -158,10 +171,12 @@ namespace Umbraco.Tests.Components
|
||||
public void Requires1()
|
||||
{
|
||||
var container = MockContainer();
|
||||
var composition = new Composition(container, RuntimeLevel.Unknown);
|
||||
|
||||
var thing = new BootLoader(container);
|
||||
var types = new[] { typeof(Component6), typeof(Component7), typeof(Component8) };
|
||||
var components = new Core.Components.Components(composition, types, Mock.Of<IProfilingLogger>());
|
||||
Composed.Clear();
|
||||
thing.Boot(new[] { typeof(Component6), typeof(Component7), typeof(Component8) }, RuntimeLevel.Unknown);
|
||||
components.Compose();
|
||||
Assert.AreEqual(2, Composed.Count);
|
||||
Assert.AreEqual(typeof(Component6), Composed[0]);
|
||||
Assert.AreEqual(typeof(Component8), Composed[1]);
|
||||
@@ -171,10 +186,12 @@ namespace Umbraco.Tests.Components
|
||||
public void Requires2A()
|
||||
{
|
||||
var container = MockContainer();
|
||||
var composition = new Composition(container, RuntimeLevel.Unknown);
|
||||
|
||||
var thing = new BootLoader(container);
|
||||
var types = new[] { typeof(Component9), typeof(Component2), typeof(Component4) };
|
||||
var components = new Core.Components.Components(composition, types, Mock.Of<IProfilingLogger>());
|
||||
Composed.Clear();
|
||||
thing.Boot(new[] { typeof(Component9), typeof(Component2), typeof(Component4) }, RuntimeLevel.Unknown);
|
||||
components.Compose();
|
||||
Assert.AreEqual(2, Composed.Count);
|
||||
Assert.AreEqual(typeof(Component4), Composed[0]);
|
||||
Assert.AreEqual(typeof(Component2), Composed[1]);
|
||||
@@ -185,10 +202,13 @@ namespace Umbraco.Tests.Components
|
||||
public void Requires2B()
|
||||
{
|
||||
var container = MockContainer();
|
||||
var composition = new Composition(container, RuntimeLevel.Run);
|
||||
|
||||
var thing = new BootLoader(container);
|
||||
var types = new[] { typeof(Component9), typeof(Component2), typeof(Component4) };
|
||||
var components = new Core.Components.Components(composition, types, Mock.Of<IProfilingLogger>());
|
||||
Composed.Clear();
|
||||
thing.Boot(new[] { typeof(Component9), typeof(Component2), typeof(Component4) }, RuntimeLevel.Run);
|
||||
components.Compose();
|
||||
components.Initialize();
|
||||
Assert.AreEqual(3, Composed.Count);
|
||||
Assert.AreEqual(typeof(Component4), Composed[0]);
|
||||
Assert.AreEqual(typeof(Component2), Composed[1]);
|
||||
@@ -199,24 +219,29 @@ namespace Umbraco.Tests.Components
|
||||
public void WeakDependencies()
|
||||
{
|
||||
var container = MockContainer();
|
||||
var composition = new Composition(container, RuntimeLevel.Unknown);
|
||||
|
||||
var thing = new BootLoader(container);
|
||||
var types = new[] { typeof(Component10) };
|
||||
var components = new Core.Components.Components(composition, types, Mock.Of<IProfilingLogger>());
|
||||
Composed.Clear();
|
||||
thing.Boot(new[] { typeof(Component10) }, RuntimeLevel.Unknown);
|
||||
components.Compose();
|
||||
Assert.AreEqual(1, Composed.Count);
|
||||
Assert.AreEqual(typeof(Component10), Composed[0]);
|
||||
|
||||
thing = new BootLoader(container);
|
||||
types = new[] { typeof(Component11) };
|
||||
components = new Core.Components.Components(composition, types, Mock.Of<IProfilingLogger>());
|
||||
Composed.Clear();
|
||||
Assert.Throws<Exception>(() => thing.Boot(new[] { typeof(Component11) }, RuntimeLevel.Unknown));
|
||||
Assert.Throws<Exception>(() => components.Compose());
|
||||
|
||||
thing = new BootLoader(container);
|
||||
types = new[] { typeof(Component2) };
|
||||
components = new Core.Components.Components(composition, types, Mock.Of<IProfilingLogger>());
|
||||
Composed.Clear();
|
||||
Assert.Throws<Exception>(() => thing.Boot(new[] { typeof(Component2) }, RuntimeLevel.Unknown));
|
||||
Assert.Throws<Exception>(() => components.Compose());
|
||||
|
||||
thing = new BootLoader(container);
|
||||
types = new[] { typeof(Component12) };
|
||||
components = new Core.Components.Components(composition, types, Mock.Of<IProfilingLogger>());
|
||||
Composed.Clear();
|
||||
thing.Boot(new[] { typeof(Component12) }, RuntimeLevel.Unknown);
|
||||
components.Compose();
|
||||
Assert.AreEqual(1, Composed.Count);
|
||||
Assert.AreEqual(typeof(Component12), Composed[0]);
|
||||
}
|
||||
@@ -225,10 +250,12 @@ namespace Umbraco.Tests.Components
|
||||
public void DisableMissing()
|
||||
{
|
||||
var container = MockContainer();
|
||||
var composition = new Composition(container, RuntimeLevel.Unknown);
|
||||
|
||||
var thing = new BootLoader(container);
|
||||
var types = new[] { typeof(Component6), typeof(Component8) }; // 8 disables 7 which is not in the list
|
||||
var components = new Core.Components.Components(composition, types, Mock.Of<IProfilingLogger>());
|
||||
Composed.Clear();
|
||||
thing.Boot(new[] { typeof(Component6), typeof(Component8) }, RuntimeLevel.Unknown); // 8 disables 7 which is not in the list
|
||||
components.Compose();
|
||||
Assert.AreEqual(2, Composed.Count);
|
||||
Assert.AreEqual(typeof(Component6), Composed[0]);
|
||||
Assert.AreEqual(typeof(Component8), Composed[1]);
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Components;
|
||||
|
||||
namespace Umbraco.Tests.Composing
|
||||
{
|
||||
@@ -11,6 +12,7 @@ namespace Umbraco.Tests.Composing
|
||||
public class CollectionBuildersTests
|
||||
{
|
||||
private IContainer _container;
|
||||
private Composition _composition;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
@@ -18,6 +20,7 @@ namespace Umbraco.Tests.Composing
|
||||
Current.Reset();
|
||||
|
||||
_container = Current.Container = ContainerFactory.Create();
|
||||
_composition = new Composition(_container, RuntimeLevel.Run);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
@@ -32,7 +35,7 @@ namespace Umbraco.Tests.Composing
|
||||
[Test]
|
||||
public void ContainsTypes()
|
||||
{
|
||||
var builder = _container.RegisterCollectionBuilder<TestCollectionBuilder>()
|
||||
var builder = _composition.GetCollectionBuilder<TestCollectionBuilder>()
|
||||
.Append<Resolved1>()
|
||||
.Append<Resolved2>();
|
||||
|
||||
@@ -48,7 +51,7 @@ namespace Umbraco.Tests.Composing
|
||||
[Test]
|
||||
public void CanClearBuilderBeforeCollectionIsCreated()
|
||||
{
|
||||
var builder = _container.RegisterCollectionBuilder<TestCollectionBuilder>()
|
||||
var builder = _composition.GetCollectionBuilder<TestCollectionBuilder>()
|
||||
.Append<Resolved1>()
|
||||
.Append<Resolved2>();
|
||||
|
||||
@@ -63,7 +66,7 @@ namespace Umbraco.Tests.Composing
|
||||
[Test]
|
||||
public void CannotClearBuilderOnceCollectionIsCreated()
|
||||
{
|
||||
var builder = _container.RegisterCollectionBuilder<TestCollectionBuilder>()
|
||||
var builder = _composition.GetCollectionBuilder<TestCollectionBuilder>()
|
||||
.Append<Resolved1>()
|
||||
.Append<Resolved2>();
|
||||
|
||||
@@ -75,7 +78,7 @@ namespace Umbraco.Tests.Composing
|
||||
[Test]
|
||||
public void CanAppendToBuilder()
|
||||
{
|
||||
var builder = _container.RegisterCollectionBuilder<TestCollectionBuilder>();
|
||||
var builder = _composition.GetCollectionBuilder<TestCollectionBuilder>();
|
||||
builder.Append<Resolved1>();
|
||||
builder.Append<Resolved2>();
|
||||
|
||||
@@ -90,7 +93,7 @@ namespace Umbraco.Tests.Composing
|
||||
[Test]
|
||||
public void CannotAppendToBuilderOnceCollectionIsCreated()
|
||||
{
|
||||
var builder = _container.RegisterCollectionBuilder<TestCollectionBuilder>();
|
||||
var builder = _composition.GetCollectionBuilder<TestCollectionBuilder>();
|
||||
|
||||
var col = builder.CreateCollection();
|
||||
|
||||
@@ -102,7 +105,7 @@ namespace Umbraco.Tests.Composing
|
||||
[Test]
|
||||
public void CanAppendDuplicateToBuilderAndDeDuplicate()
|
||||
{
|
||||
var builder = _container.RegisterCollectionBuilder<TestCollectionBuilder>();
|
||||
var builder = _composition.GetCollectionBuilder<TestCollectionBuilder>();
|
||||
builder.Append<Resolved1>();
|
||||
builder.Append<Resolved1>();
|
||||
|
||||
@@ -113,7 +116,7 @@ namespace Umbraco.Tests.Composing
|
||||
[Test]
|
||||
public void CannotAppendInvalidTypeToBUilder()
|
||||
{
|
||||
var builder = _container.RegisterCollectionBuilder<TestCollectionBuilder>();
|
||||
var builder = _composition.GetCollectionBuilder<TestCollectionBuilder>();
|
||||
//builder.Append<Resolved4>(); // does not compile
|
||||
Assert.Throws<InvalidOperationException>(() =>
|
||||
builder.Append(new[] { typeof (Resolved4) }) // throws
|
||||
@@ -123,7 +126,7 @@ namespace Umbraco.Tests.Composing
|
||||
[Test]
|
||||
public void CanRemoveFromBuilder()
|
||||
{
|
||||
var builder = _container.RegisterCollectionBuilder<TestCollectionBuilder>()
|
||||
var builder = _composition.GetCollectionBuilder<TestCollectionBuilder>()
|
||||
.Append<Resolved1>()
|
||||
.Append<Resolved2>()
|
||||
.Remove<Resolved2>();
|
||||
@@ -139,7 +142,7 @@ namespace Umbraco.Tests.Composing
|
||||
[Test]
|
||||
public void CanRemoveMissingFromBuilder()
|
||||
{
|
||||
var builder = _container.RegisterCollectionBuilder<TestCollectionBuilder>()
|
||||
var builder = _composition.GetCollectionBuilder<TestCollectionBuilder>()
|
||||
.Append<Resolved1>()
|
||||
.Append<Resolved2>()
|
||||
.Remove<Resolved3>();
|
||||
@@ -151,7 +154,7 @@ namespace Umbraco.Tests.Composing
|
||||
[Test]
|
||||
public void CannotRemoveFromBuilderOnceCollectionIsCreated()
|
||||
{
|
||||
var builder = _container.RegisterCollectionBuilder<TestCollectionBuilder>()
|
||||
var builder = _composition.GetCollectionBuilder<TestCollectionBuilder>()
|
||||
.Append<Resolved1>()
|
||||
.Append<Resolved2>();
|
||||
|
||||
@@ -164,7 +167,7 @@ namespace Umbraco.Tests.Composing
|
||||
[Test]
|
||||
public void CanInsertIntoBuilder()
|
||||
{
|
||||
var builder = _container.RegisterCollectionBuilder<TestCollectionBuilder>()
|
||||
var builder = _composition.GetCollectionBuilder<TestCollectionBuilder>()
|
||||
.Append<Resolved1>()
|
||||
.Append<Resolved2>()
|
||||
.Insert<Resolved3>();
|
||||
@@ -180,7 +183,7 @@ namespace Umbraco.Tests.Composing
|
||||
[Test]
|
||||
public void CannotInsertIntoBuilderOnceCollectionIsCreated()
|
||||
{
|
||||
var builder = _container.RegisterCollectionBuilder<TestCollectionBuilder>()
|
||||
var builder = _composition.GetCollectionBuilder<TestCollectionBuilder>()
|
||||
.Append<Resolved1>()
|
||||
.Append<Resolved2>();
|
||||
|
||||
@@ -193,7 +196,7 @@ namespace Umbraco.Tests.Composing
|
||||
[Test]
|
||||
public void CanInsertDuplicateIntoBuilderAndDeDuplicate()
|
||||
{
|
||||
var builder = _container.RegisterCollectionBuilder<TestCollectionBuilder>()
|
||||
var builder = _composition.GetCollectionBuilder<TestCollectionBuilder>()
|
||||
.Append<Resolved1>()
|
||||
.Append<Resolved2>()
|
||||
.Insert<Resolved2>();
|
||||
@@ -205,7 +208,7 @@ namespace Umbraco.Tests.Composing
|
||||
[Test]
|
||||
public void CanInsertIntoEmptyBuilder()
|
||||
{
|
||||
var builder = _container.RegisterCollectionBuilder<TestCollectionBuilder>();
|
||||
var builder = _composition.GetCollectionBuilder<TestCollectionBuilder>();
|
||||
builder.Insert<Resolved2>();
|
||||
|
||||
var col = builder.CreateCollection();
|
||||
@@ -215,7 +218,7 @@ namespace Umbraco.Tests.Composing
|
||||
[Test]
|
||||
public void CannotInsertIntoBuilderAtWrongIndex()
|
||||
{
|
||||
var builder = _container.RegisterCollectionBuilder<TestCollectionBuilder>()
|
||||
var builder = _composition.GetCollectionBuilder<TestCollectionBuilder>()
|
||||
.Append<Resolved1>()
|
||||
.Append<Resolved2>();
|
||||
|
||||
@@ -231,7 +234,7 @@ namespace Umbraco.Tests.Composing
|
||||
[Test]
|
||||
public void CanInsertIntoBuilderBefore()
|
||||
{
|
||||
var builder = _container.RegisterCollectionBuilder<TestCollectionBuilder>()
|
||||
var builder = _composition.GetCollectionBuilder<TestCollectionBuilder>()
|
||||
.Append<Resolved1>()
|
||||
.Append<Resolved2>()
|
||||
.InsertBefore<Resolved2, Resolved3>();
|
||||
@@ -247,7 +250,7 @@ namespace Umbraco.Tests.Composing
|
||||
[Test]
|
||||
public void CannotInsertIntoBuilderBeforeOnceCollectionIsCreated()
|
||||
{
|
||||
var builder = _container.RegisterCollectionBuilder<TestCollectionBuilder>()
|
||||
var builder = _composition.GetCollectionBuilder<TestCollectionBuilder>()
|
||||
.Append<Resolved1>()
|
||||
.Append<Resolved2>();
|
||||
|
||||
@@ -260,7 +263,7 @@ namespace Umbraco.Tests.Composing
|
||||
[Test]
|
||||
public void CanInsertDuplicateIntoBuilderBeforeAndDeDuplicate()
|
||||
{
|
||||
var builder = _container.RegisterCollectionBuilder<TestCollectionBuilder>()
|
||||
var builder = _composition.GetCollectionBuilder<TestCollectionBuilder>()
|
||||
.Append<Resolved1>()
|
||||
.Append<Resolved2>()
|
||||
.InsertBefore<Resolved1, Resolved2>();
|
||||
@@ -272,7 +275,7 @@ namespace Umbraco.Tests.Composing
|
||||
[Test]
|
||||
public void CannotInsertIntoBuilderBeforeMissing()
|
||||
{
|
||||
var builder = _container.RegisterCollectionBuilder<TestCollectionBuilder>()
|
||||
var builder = _composition.GetCollectionBuilder<TestCollectionBuilder>()
|
||||
.Append<Resolved1>();
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() =>
|
||||
@@ -283,7 +286,7 @@ namespace Umbraco.Tests.Composing
|
||||
[Test]
|
||||
public void ScopeBuilderCreatesScopedCollection()
|
||||
{
|
||||
_container.RegisterCollectionBuilder<TestCollectionBuilder>()
|
||||
_composition.GetCollectionBuilder<TestCollectionBuilder>()
|
||||
.Append<Resolved1>()
|
||||
.Append<Resolved2>();
|
||||
|
||||
@@ -303,7 +306,7 @@ namespace Umbraco.Tests.Composing
|
||||
[Test]
|
||||
public void TransientBuilderCreatesTransientCollection()
|
||||
{
|
||||
_container.RegisterCollectionBuilder<TestCollectionBuilderTransient>()
|
||||
_composition.GetCollectionBuilder<TestCollectionBuilderTransient>()
|
||||
.Append<Resolved1>()
|
||||
.Append<Resolved2>();
|
||||
|
||||
@@ -323,7 +326,7 @@ namespace Umbraco.Tests.Composing
|
||||
[Test]
|
||||
public void BuilderRespectsTypesOrder()
|
||||
{
|
||||
var builder = _container.RegisterCollectionBuilder<TestCollectionBuilderTransient>()
|
||||
var builder = _composition.GetCollectionBuilder<TestCollectionBuilderTransient>()
|
||||
.Append<Resolved3>()
|
||||
.Insert<Resolved1>()
|
||||
.InsertBefore<Resolved3, Resolved2>();
|
||||
@@ -335,7 +338,7 @@ namespace Umbraco.Tests.Composing
|
||||
[Test]
|
||||
public void ScopeBuilderRespectsContainerScope()
|
||||
{
|
||||
_container.RegisterCollectionBuilder<TestCollectionBuilderScope>()
|
||||
_composition.GetCollectionBuilder<TestCollectionBuilderScope>()
|
||||
.Append<Resolved1>()
|
||||
.Append<Resolved2>();
|
||||
|
||||
@@ -369,7 +372,7 @@ namespace Umbraco.Tests.Composing
|
||||
[Test]
|
||||
public void WeightedBuilderCreatesWeightedCollection()
|
||||
{
|
||||
var builder = _container.RegisterCollectionBuilder<TestCollectionBuilderWeighted>()
|
||||
var builder = _composition.GetCollectionBuilder<TestCollectionBuilderWeighted>()
|
||||
.Add<Resolved1>()
|
||||
.Add<Resolved2>();
|
||||
|
||||
@@ -434,20 +437,12 @@ namespace Umbraco.Tests.Composing
|
||||
// ReSharper disable once ClassNeverInstantiated.Local
|
||||
private class TestCollectionBuilder : OrderedCollectionBuilderBase<TestCollectionBuilder, TestCollection, Resolved>
|
||||
{
|
||||
public TestCollectionBuilder(IContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
protected override TestCollectionBuilder This => this;
|
||||
}
|
||||
|
||||
// ReSharper disable once ClassNeverInstantiated.Local
|
||||
private class TestCollectionBuilderTransient : OrderedCollectionBuilderBase<TestCollectionBuilderTransient, TestCollection, Resolved>
|
||||
{
|
||||
public TestCollectionBuilderTransient(IContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
protected override TestCollectionBuilderTransient This => this;
|
||||
|
||||
protected override Lifetime CollectionLifetime => Lifetime.Transient; // transient
|
||||
@@ -456,10 +451,6 @@ namespace Umbraco.Tests.Composing
|
||||
// ReSharper disable once ClassNeverInstantiated.Local
|
||||
private class TestCollectionBuilderScope : OrderedCollectionBuilderBase<TestCollectionBuilderScope, TestCollection, Resolved>
|
||||
{
|
||||
public TestCollectionBuilderScope(IContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
protected override TestCollectionBuilderScope This => this;
|
||||
|
||||
protected override Lifetime CollectionLifetime => Lifetime.Scope;
|
||||
@@ -468,10 +459,6 @@ namespace Umbraco.Tests.Composing
|
||||
// ReSharper disable once ClassNeverInstantiated.Local
|
||||
private class TestCollectionBuilderWeighted : WeightedCollectionBuilderBase<TestCollectionBuilderWeighted, TestCollection, Resolved>
|
||||
{
|
||||
public TestCollectionBuilderWeighted(IContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
protected override TestCollectionBuilderWeighted This => this;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Components;
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Tests.Composing
|
||||
@@ -33,8 +34,9 @@ namespace Umbraco.Tests.Composing
|
||||
public void LazyCollectionBuilderHandlesTypes()
|
||||
{
|
||||
var container = CreateContainer();
|
||||
var composition = new Composition(container, RuntimeLevel.Run);
|
||||
|
||||
container.RegisterCollectionBuilder<TestCollectionBuilder>()
|
||||
composition.GetCollectionBuilder<TestCollectionBuilder>()
|
||||
.Add<TransientObject3>()
|
||||
.Add<TransientObject2>()
|
||||
.Add<TransientObject3>()
|
||||
@@ -56,8 +58,9 @@ namespace Umbraco.Tests.Composing
|
||||
public void LazyCollectionBuilderHandlesProducers()
|
||||
{
|
||||
var container = CreateContainer();
|
||||
var composition = new Composition(container, RuntimeLevel.Run);
|
||||
|
||||
container.RegisterCollectionBuilder<TestCollectionBuilder>()
|
||||
composition.GetCollectionBuilder<TestCollectionBuilder>()
|
||||
.Add(() => new[] { typeof(TransientObject3), typeof(TransientObject2) })
|
||||
.Add(() => new[] { typeof(TransientObject3), typeof(TransientObject2) })
|
||||
.Add(() => new[] { typeof(TransientObject1) });
|
||||
@@ -78,8 +81,9 @@ namespace Umbraco.Tests.Composing
|
||||
public void LazyCollectionBuilderHandlesTypesAndProducers()
|
||||
{
|
||||
var container = CreateContainer();
|
||||
var composition = new Composition(container, RuntimeLevel.Run);
|
||||
|
||||
container.RegisterCollectionBuilder<TestCollectionBuilder>()
|
||||
composition.GetCollectionBuilder<TestCollectionBuilder>()
|
||||
.Add<TransientObject3>()
|
||||
.Add<TransientObject2>()
|
||||
.Add<TransientObject3>()
|
||||
@@ -101,8 +105,9 @@ namespace Umbraco.Tests.Composing
|
||||
public void LazyCollectionBuilderThrowsOnIllegalTypes()
|
||||
{
|
||||
var container = CreateContainer();
|
||||
var composition = new Composition(container, RuntimeLevel.Run);
|
||||
|
||||
container.RegisterCollectionBuilder<TestCollectionBuilder>()
|
||||
composition.GetCollectionBuilder<TestCollectionBuilder>()
|
||||
.Add<TransientObject3>()
|
||||
|
||||
// illegal, does not implement the interface!
|
||||
@@ -122,8 +127,9 @@ namespace Umbraco.Tests.Composing
|
||||
public void LazyCollectionBuilderCanExcludeTypes()
|
||||
{
|
||||
var container = CreateContainer();
|
||||
var composition = new Composition(container, RuntimeLevel.Run);
|
||||
|
||||
container.RegisterCollectionBuilder<TestCollectionBuilder>()
|
||||
composition.GetCollectionBuilder<TestCollectionBuilder>()
|
||||
.Add<TransientObject3>()
|
||||
.Add(() => new[] { typeof(TransientObject3), typeof(TransientObject2), typeof(TransientObject1) })
|
||||
.Exclude<TransientObject3>();
|
||||
@@ -162,10 +168,6 @@ namespace Umbraco.Tests.Composing
|
||||
// ReSharper disable once ClassNeverInstantiated.Local
|
||||
private class TestCollectionBuilder : LazyCollectionBuilderBase<TestCollectionBuilder, TestCollection, ITestInterface>
|
||||
{
|
||||
public TestCollectionBuilder(IContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
protected override TestCollectionBuilder This => this;
|
||||
|
||||
protected override Lifetime CollectionLifetime => Lifetime.Transient; // transient
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Components;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core._Legacy.PackageActions;
|
||||
|
||||
@@ -14,8 +16,9 @@ namespace Umbraco.Tests.Composing
|
||||
public void PackageActionCollectionBuilderWorks()
|
||||
{
|
||||
var container = Current.Container = ContainerFactory.Create();
|
||||
var composition = new Composition(container, RuntimeLevel.Run);
|
||||
|
||||
container.RegisterCollectionBuilder<PackageActionCollectionBuilder>()
|
||||
composition.GetCollectionBuilder<PackageActionCollectionBuilder>()
|
||||
.Add(() => TypeLoader.GetPackageActions());
|
||||
|
||||
var actions = Current.PackageActions;
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace Umbraco.Tests.Integration
|
||||
Container.Register<IServerRegistrar>(_ => new TestServerRegistrar()); // localhost-only
|
||||
Container.RegisterSingleton<IServerMessenger, LocalServerMessenger>();
|
||||
|
||||
Container.RegisterCollectionBuilder<CacheRefresherCollectionBuilder>()
|
||||
Composition.GetCollectionBuilder<CacheRefresherCollectionBuilder>()
|
||||
.Add<ContentTypeCacheRefresher>()
|
||||
.Add<ContentCacheRefresher>()
|
||||
.Add<MacroCacheRefresher>();
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Umbraco.Tests.Misc
|
||||
[Test]
|
||||
public void NoApplicationUrlByDefault()
|
||||
{
|
||||
var state = new RuntimeState(Mock.Of<ILogger>(), new Lazy<IServerRegistrar>(Mock.Of<IServerRegistrar>), new Lazy<MainDom>(Mock.Of<MainDom>), Mock.Of<IUmbracoSettingsSection>(), Mock.Of<IGlobalSettings>());
|
||||
var state = new RuntimeState(Mock.Of<ILogger>(), Mock.Of<IUmbracoSettingsSection>(), Mock.Of<IGlobalSettings>(), new Lazy<MainDom>(), new Lazy<IServerRegistrar>());
|
||||
Assert.IsNull(state.ApplicationUrl);
|
||||
}
|
||||
|
||||
@@ -46,10 +46,7 @@ namespace Umbraco.Tests.Misc
|
||||
var registrar = new Mock<IServerRegistrar>();
|
||||
registrar.Setup(x => x.GetCurrentServerUmbracoApplicationUrl()).Returns("http://server1.com/umbraco");
|
||||
|
||||
var state = new RuntimeState(
|
||||
Mock.Of<ILogger>(),
|
||||
new Lazy<IServerRegistrar>(() => registrar.Object),
|
||||
new Lazy<MainDom>(Mock.Of<MainDom>), settings, globalConfig.Object);
|
||||
var state = new RuntimeState(Mock.Of<ILogger>(), settings, globalConfig.Object, new Lazy<MainDom>(), new Lazy<IServerRegistrar>(() => registrar.Object));
|
||||
|
||||
state.EnsureApplicationUrl();
|
||||
|
||||
@@ -72,7 +69,7 @@ namespace Umbraco.Tests.Misc
|
||||
|
||||
|
||||
|
||||
var state = new RuntimeState(Mock.Of<ILogger>(), new Lazy<IServerRegistrar>(Mock.Of<IServerRegistrar>), new Lazy<MainDom>(Mock.Of<MainDom>), settings, globalConfig.Object);
|
||||
var state = new RuntimeState(Mock.Of<ILogger>(), settings, globalConfig.Object, new Lazy<MainDom>(), new Lazy<IServerRegistrar>(() => Mock.Of<IServerRegistrar>()));
|
||||
|
||||
state.EnsureApplicationUrl();
|
||||
|
||||
@@ -147,7 +144,5 @@ namespace Umbraco.Tests.Misc
|
||||
|
||||
Assert.AreEqual("httpx://whatever.com/umbraco", url);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Umbraco.Tests.Models.Mapping
|
||||
Container.Register(_ => manifestBuilder);
|
||||
|
||||
Func<IEnumerable<Type>> typeListProducerList = Enumerable.Empty<Type>;
|
||||
Container.GetInstance<DataEditorCollectionBuilder>()
|
||||
Composition.GetCollectionBuilder<DataEditorCollectionBuilder>()
|
||||
.Clear()
|
||||
.Add(typeListProducerList);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace Umbraco.Tests.Persistence
|
||||
_sqlCeSyntaxProvider = new SqlCeSyntaxProvider();
|
||||
_sqlSyntaxProviders = new[] { (ISqlSyntaxProvider) _sqlCeSyntaxProvider };
|
||||
_logger = Mock.Of<ILogger>();
|
||||
_databaseFactory = new UmbracoDatabaseFactory(_sqlSyntaxProviders, _logger, Mock.Of<IMapperCollection>());
|
||||
_databaseFactory = new UmbracoDatabaseFactory(_logger, new Lazy<IMapperCollection>(() => Mock.Of<IMapperCollection>()));
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
@@ -76,7 +76,7 @@ namespace Umbraco.Tests.Persistence
|
||||
}
|
||||
|
||||
// re-create the database factory and database context with proper connection string
|
||||
_databaseFactory = new UmbracoDatabaseFactory(connString, Constants.DbProviderNames.SqlCe, _sqlSyntaxProviders, _logger, Mock.Of<IMapperCollection>());
|
||||
_databaseFactory = new UmbracoDatabaseFactory(connString, Constants.DbProviderNames.SqlCe, _logger, new Lazy<IMapperCollection>(() => Mock.Of<IMapperCollection>()));
|
||||
|
||||
// create application context
|
||||
//var appCtx = new ApplicationContext(
|
||||
|
||||
@@ -19,8 +19,7 @@ namespace Umbraco.Tests.Persistence.FaultHandling
|
||||
{
|
||||
const string connectionString = @"server=.\SQLEXPRESS;database=EmptyForTest;user id=x;password=umbraco";
|
||||
const string providerName = Constants.DbProviderNames.SqlServer;
|
||||
var sqlSyntax = new[] { new SqlServerSyntaxProvider(new Lazy<IScopeProvider>(() => null)) };
|
||||
var factory = new UmbracoDatabaseFactory(connectionString, providerName, sqlSyntax, Mock.Of<ILogger>(), Mock.Of<IMapperCollection>());
|
||||
var factory = new UmbracoDatabaseFactory(connectionString, providerName, Mock.Of<ILogger>(), new Lazy<IMapperCollection>(() => Mock.Of<IMapperCollection>()));
|
||||
|
||||
using (var database = factory.CreateDatabase())
|
||||
{
|
||||
@@ -34,8 +33,7 @@ namespace Umbraco.Tests.Persistence.FaultHandling
|
||||
{
|
||||
const string connectionString = @"server=.\SQLEXPRESS;database=EmptyForTest;user id=umbraco;password=umbraco";
|
||||
const string providerName = Constants.DbProviderNames.SqlServer;
|
||||
var sqlSyntax = new[] { new SqlServerSyntaxProvider(new Lazy<IScopeProvider>(() => null)) };
|
||||
var factory = new UmbracoDatabaseFactory(connectionString, providerName, sqlSyntax, Mock.Of<ILogger>(), Mock.Of<IMapperCollection>());
|
||||
var factory = new UmbracoDatabaseFactory(connectionString, providerName, Mock.Of<ILogger>(), new Lazy<IMapperCollection>(() => Mock.Of<IMapperCollection>()));
|
||||
|
||||
using (var database = factory.CreateDatabase())
|
||||
{
|
||||
|
||||
@@ -670,7 +670,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
[Test]
|
||||
public void AliasRegexTest()
|
||||
{
|
||||
var regex = new SqlServerSyntaxProvider(new Lazy<IScopeProvider>(() => null)).AliasRegex;
|
||||
var regex = new SqlServerSyntaxProvider().AliasRegex;
|
||||
Assert.AreEqual(@"(\[\w+]\.\[\w+])\s+AS\s+(\[\w+])", regex.ToString());
|
||||
const string sql = "SELECT [table].[column1] AS [alias1], [table].[column2] AS [alias2] FROM [table];";
|
||||
var matches = regex.Matches(sql);
|
||||
|
||||
@@ -74,7 +74,7 @@ WHERE (([umbracoNode].[nodeObjectType] = @0))) x)".Replace(Environment.NewLine,
|
||||
[Test]
|
||||
public void Format_SqlServer_NonClusteredIndexDefinition_AddsNonClusteredDirective()
|
||||
{
|
||||
var sqlSyntax = new SqlServerSyntaxProvider(new Lazy<IScopeProvider>(() => null));
|
||||
var sqlSyntax = new SqlServerSyntaxProvider();
|
||||
|
||||
var indexDefinition = CreateIndexDefinition();
|
||||
indexDefinition.IndexType = IndexTypes.NonClustered;
|
||||
@@ -86,7 +86,7 @@ WHERE (([umbracoNode].[nodeObjectType] = @0))) x)".Replace(Environment.NewLine,
|
||||
[Test]
|
||||
public void Format_SqlServer_NonClusteredIndexDefinition_UsingIsClusteredFalse_AddsClusteredDirective()
|
||||
{
|
||||
var sqlSyntax = new SqlServerSyntaxProvider(new Lazy<IScopeProvider>(() => null));
|
||||
var sqlSyntax = new SqlServerSyntaxProvider();
|
||||
|
||||
var indexDefinition = CreateIndexDefinition();
|
||||
indexDefinition.IndexType = IndexTypes.Clustered;
|
||||
@@ -99,7 +99,7 @@ WHERE (([umbracoNode].[nodeObjectType] = @0))) x)".Replace(Environment.NewLine,
|
||||
public void CreateIndexBuilder_SqlServer_NonClustered_CreatesNonClusteredIndex()
|
||||
{
|
||||
var logger = Mock.Of<ILogger>();
|
||||
var sqlSyntax = new SqlServerSyntaxProvider(new Lazy<IScopeProvider>(() => null));
|
||||
var sqlSyntax = new SqlServerSyntaxProvider();
|
||||
var db = new TestDatabase(DatabaseType.SqlServer2005, sqlSyntax);
|
||||
var context = new MigrationContext(db, logger);
|
||||
|
||||
@@ -120,7 +120,7 @@ WHERE (([umbracoNode].[nodeObjectType] = @0))) x)".Replace(Environment.NewLine,
|
||||
public void CreateIndexBuilder_SqlServer_Unique_CreatesUniqueNonClusteredIndex()
|
||||
{
|
||||
var logger = Mock.Of<ILogger>();
|
||||
var sqlSyntax = new SqlServerSyntaxProvider(new Lazy<IScopeProvider>(() => null));
|
||||
var sqlSyntax = new SqlServerSyntaxProvider();
|
||||
var db = new TestDatabase(DatabaseType.SqlServer2005, sqlSyntax);
|
||||
var context = new MigrationContext(db, logger);
|
||||
|
||||
@@ -141,7 +141,7 @@ WHERE (([umbracoNode].[nodeObjectType] = @0))) x)".Replace(Environment.NewLine,
|
||||
public void CreateIndexBuilder_SqlServer_Unique_CreatesUniqueNonClusteredIndex_Multi_Columnn()
|
||||
{
|
||||
var logger = Mock.Of<ILogger>();
|
||||
var sqlSyntax = new SqlServerSyntaxProvider(new Lazy<IScopeProvider>(() => null));
|
||||
var sqlSyntax = new SqlServerSyntaxProvider();
|
||||
var db = new TestDatabase(DatabaseType.SqlServer2005, sqlSyntax);
|
||||
var context = new MigrationContext(db, logger);
|
||||
|
||||
@@ -162,7 +162,7 @@ WHERE (([umbracoNode].[nodeObjectType] = @0))) x)".Replace(Environment.NewLine,
|
||||
public void CreateIndexBuilder_SqlServer_Clustered_CreatesClusteredIndex()
|
||||
{
|
||||
var logger = Mock.Of<ILogger>();
|
||||
var sqlSyntax = new SqlServerSyntaxProvider(new Lazy<IScopeProvider>(() => null));
|
||||
var sqlSyntax = new SqlServerSyntaxProvider();
|
||||
var db = new TestDatabase(DatabaseType.SqlServer2005, sqlSyntax);
|
||||
var context = new MigrationContext(db, logger);
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Components;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.IO;
|
||||
@@ -67,8 +68,9 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
try
|
||||
{
|
||||
var container = Current.Container = ContainerFactory.Create();
|
||||
var composition = new Composition(container, RuntimeLevel.Run);
|
||||
|
||||
container.RegisterCollectionBuilder<PropertyValueConverterCollectionBuilder>();
|
||||
composition.GetCollectionBuilder<PropertyValueConverterCollectionBuilder>();
|
||||
|
||||
var logger = Mock.Of<ILogger>();
|
||||
var scheme = Mock.Of<IMediaPathScheme>();
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Components;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
@@ -172,9 +173,9 @@ namespace Umbraco.Tests.Published
|
||||
{
|
||||
Current.Reset();
|
||||
var container = Current.Container = ContainerFactory.Create();
|
||||
var composition = new Composition(container, RuntimeLevel.Run);
|
||||
|
||||
|
||||
Current.Container.RegisterCollectionBuilder<PropertyValueConverterCollectionBuilder>()
|
||||
composition.GetCollectionBuilder<PropertyValueConverterCollectionBuilder>()
|
||||
.Append<SimpleConverter3A>()
|
||||
.Append<SimpleConverter3B>();
|
||||
|
||||
|
||||
@@ -23,10 +23,8 @@ namespace Umbraco.Tests.PublishedContent
|
||||
// fixme - what about the if (PropertyValueConvertersResolver.HasCurrent == false) ??
|
||||
// can we risk double - registering and then, what happens?
|
||||
|
||||
var builder = Container.TryGetInstance<PropertyValueConverterCollectionBuilder>()
|
||||
?? Container.RegisterCollectionBuilder<PropertyValueConverterCollectionBuilder>();
|
||||
|
||||
builder.Clear()
|
||||
Composition.GetCollectionBuilder<PropertyValueConverterCollectionBuilder>()
|
||||
.Clear()
|
||||
.Append<DatePickerValueConverter>()
|
||||
.Append<TinyMceValueConverter>()
|
||||
.Append<YesNoValueConverter>();
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
{
|
||||
base.Compose();
|
||||
|
||||
Container.GetInstance<UrlSegmentProviderCollectionBuilder>()
|
||||
Composition.GetCollectionBuilder<UrlSegmentProviderCollectionBuilder>()
|
||||
.Clear()
|
||||
.Append<DefaultUrlSegmentProvider>();
|
||||
}
|
||||
|
||||
@@ -32,7 +32,8 @@ namespace Umbraco.Tests.Routing
|
||||
//create the module
|
||||
var logger = Mock.Of<ILogger>();
|
||||
var globalSettings = TestObjects.GetGlobalSettings();
|
||||
var runtime = new RuntimeState(logger, new Lazy<IServerRegistrar>(), new Lazy<MainDom>(), Mock.Of<IUmbracoSettingsSection>(), globalSettings);
|
||||
var runtime = new RuntimeState(logger, Mock.Of<IUmbracoSettingsSection>(), globalSettings,
|
||||
new Lazy<MainDom>(), new Lazy<IServerRegistrar>());
|
||||
|
||||
_module = new UmbracoInjectedModule
|
||||
(
|
||||
|
||||
@@ -74,9 +74,11 @@ namespace Umbraco.Tests.Runtimes
|
||||
return new DebugDiagnosticsLogger();
|
||||
}
|
||||
|
||||
public override void Compose(IContainer container)
|
||||
public override void Compose(Composition composition)
|
||||
{
|
||||
base.Compose(container);
|
||||
base.Compose(composition);
|
||||
|
||||
var container = composition.Container;
|
||||
|
||||
// the application's profiler and profiling logger are
|
||||
// registered by CoreRuntime.Compose() but can be
|
||||
@@ -100,7 +102,7 @@ namespace Umbraco.Tests.Runtimes
|
||||
|
||||
// pretend we have the proper migration
|
||||
// else BootFailedException because our mock IUmbracoDatabaseFactory does not provide databases
|
||||
protected override bool EnsureUmbracoUpgradeState(IUmbracoDatabaseFactory databaseFactory, ILogger logger)
|
||||
protected override bool EnsureUmbracoUpgradeState(IUmbracoDatabaseFactory databaseFactory)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -122,7 +124,7 @@ namespace Umbraco.Tests.Runtimes
|
||||
// runs with only one single component
|
||||
// UmbracoCoreComponent will be force-added too
|
||||
// and that's it
|
||||
protected override IEnumerable<Type> GetComponentTypes()
|
||||
protected override IEnumerable<Type> GetComponentTypes(TypeLoader typeLoader)
|
||||
{
|
||||
return new[] { typeof(TestComponent) };
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Linq;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Components;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.IO;
|
||||
@@ -30,11 +31,12 @@ namespace Umbraco.Tests.Scoping
|
||||
DoThing3 = null;
|
||||
|
||||
var container = Current.Container = ContainerFactory.Create();
|
||||
var composition = new Composition(container, RuntimeLevel.Run);
|
||||
|
||||
_testObjects = new TestObjects(container);
|
||||
|
||||
Current.Container.RegisterSingleton(factory => new FileSystems(container, factory.TryGetInstance<ILogger>()));
|
||||
Current.Container.RegisterCollectionBuilder<MapperCollectionBuilder>();
|
||||
composition.GetCollectionBuilder<MapperCollectionBuilder>();
|
||||
|
||||
SettingsForTests.Reset(); // ensure we have configuration
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace Umbraco.Tests.Scoping
|
||||
// so doing all this mess
|
||||
Container.RegisterSingleton<IServerMessenger, ScopedXmlTests.LocalServerMessenger>();
|
||||
Container.RegisterSingleton(f => Mock.Of<IServerRegistrar>());
|
||||
Container.RegisterCollectionBuilder<CacheRefresherCollectionBuilder>()
|
||||
Composition.GetCollectionBuilder<CacheRefresherCollectionBuilder>()
|
||||
.Add(f => f.TryGetInstance<TypeLoader>().GetCacheRefreshers());
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Umbraco.Tests.Scoping
|
||||
// so doing all this mess
|
||||
Container.RegisterSingleton<IServerMessenger, LocalServerMessenger>();
|
||||
Container.RegisterSingleton(f => Mock.Of<IServerRegistrar>());
|
||||
Container.RegisterCollectionBuilder<CacheRefresherCollectionBuilder>()
|
||||
Composition.GetCollectionBuilder<CacheRefresherCollectionBuilder>()
|
||||
.Add(f => f.TryGetInstance<TypeLoader>().GetCacheRefreshers());
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace Umbraco.Tests.Scoping
|
||||
// so doing all this mess
|
||||
Container.RegisterSingleton<IServerMessenger, LocalServerMessenger>();
|
||||
Container.RegisterSingleton(f => Mock.Of<IServerRegistrar>());
|
||||
Container.RegisterCollectionBuilder<CacheRefresherCollectionBuilder>()
|
||||
Composition.GetCollectionBuilder<CacheRefresherCollectionBuilder>()
|
||||
.Add(f => f.TryGetInstance<TypeLoader>().GetCacheRefreshers());
|
||||
}
|
||||
|
||||
|
||||
@@ -57,8 +57,7 @@ namespace Umbraco.Tests.Services
|
||||
{
|
||||
base.Compose();
|
||||
|
||||
// fixme - do it differently
|
||||
Container.Register(factory => factory.GetInstance<ServiceContext>().TextService);
|
||||
Container.RegisterSingleton(factory => Mock.Of<ILocalizedTextService>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Umbraco.Tests.Services
|
||||
// pfew - see note in ScopedNuCacheTests?
|
||||
Container.RegisterSingleton<IServerMessenger, LocalServerMessenger>();
|
||||
Container.RegisterSingleton(f => Mock.Of<IServerRegistrar>());
|
||||
Container.RegisterCollectionBuilder<CacheRefresherCollectionBuilder>()
|
||||
Composition.GetCollectionBuilder<CacheRefresherCollectionBuilder>()
|
||||
.Add(f => f.TryGetInstance<TypeLoader>().GetCacheRefreshers());
|
||||
}
|
||||
|
||||
@@ -770,4 +770,4 @@ namespace Umbraco.Tests.Services
|
||||
"{'properties':{'value11':[{'culture':'','seg':'','val':'v11'}],'value12':[{'culture':'','seg':'','val':'v12'}],'value31':[{'culture':'','seg':'','val':'v31'}],'value32':[{'culture':'','seg':'','val':'v32'}]},'cultureData':");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace Umbraco.Tests.Services.Importing
|
||||
// pollute everything, they are ignored by the type finder and explicitely
|
||||
// added to the editors collection
|
||||
|
||||
Container.GetInstance<DataEditorCollectionBuilder>()
|
||||
Composition.GetCollectionBuilder<DataEditorCollectionBuilder>()
|
||||
.Add<Editor1>()
|
||||
.Add<Editor2>();
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using NPoco;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Components;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
@@ -33,6 +34,7 @@ namespace Umbraco.Tests.TestHelpers
|
||||
var sqlSyntax = new SqlCeSyntaxProvider();
|
||||
|
||||
var container = Current.Container = ContainerFactory.Create();
|
||||
var composition = new Composition(container, RuntimeLevel.Run);
|
||||
|
||||
container.RegisterSingleton<ILogger>(factory => Mock.Of<ILogger>());
|
||||
container.RegisterSingleton<IProfiler>(factory => Mock.Of<IProfiler>());
|
||||
@@ -44,7 +46,7 @@ namespace Umbraco.Tests.TestHelpers
|
||||
false);
|
||||
container.RegisterInstance(pluginManager);
|
||||
|
||||
container.RegisterCollectionBuilder<MapperCollectionBuilder>()
|
||||
composition.GetCollectionBuilder<MapperCollectionBuilder>()
|
||||
.Add(() => Current.TypeLoader.GetAssignedMapperTypes());
|
||||
Mappers = container.GetInstance<IMapperCollection>();
|
||||
|
||||
|
||||
@@ -37,22 +37,6 @@ namespace Umbraco.Tests.TestHelpers
|
||||
_container = container;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default ISqlSyntaxProvider objects.
|
||||
/// </summary>
|
||||
/// <param name="logger">A logger.</param>
|
||||
/// <param name="lazyScopeProvider">A (lazy) scope provider.</param>
|
||||
/// <returns>The default ISqlSyntaxProvider objects.</returns>
|
||||
public IEnumerable<ISqlSyntaxProvider> GetDefaultSqlSyntaxProviders(ILogger logger, Lazy<IScopeProvider> lazyScopeProvider = null)
|
||||
{
|
||||
return new ISqlSyntaxProvider[]
|
||||
{
|
||||
new MySqlSyntaxProvider(logger),
|
||||
new SqlCeSyntaxProvider(),
|
||||
new SqlServerSyntaxProvider(lazyScopeProvider ?? new Lazy<IScopeProvider>(() => null))
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an UmbracoDatabase.
|
||||
/// </summary>
|
||||
@@ -77,7 +61,7 @@ namespace Umbraco.Tests.TestHelpers
|
||||
/// that can begin a transaction.</remarks>
|
||||
public UmbracoDatabase GetUmbracoSqlServerDatabase(ILogger logger)
|
||||
{
|
||||
var syntax = new SqlServerSyntaxProvider(new Lazy<IScopeProvider>(() => null)); // do NOT try to get the server's version!
|
||||
var syntax = new SqlServerSyntaxProvider(); // do NOT try to get the server's version!
|
||||
var connection = GetDbConnection();
|
||||
var sqlContext = new SqlContext(syntax, DatabaseType.SqlServer2008, Mock.Of<IPocoDataFactory>());
|
||||
return new UmbracoDatabase(connection, sqlContext, logger);
|
||||
@@ -241,7 +225,7 @@ namespace Umbraco.Tests.TestHelpers
|
||||
//mappersBuilder.AddCore();
|
||||
//var mappers = mappersBuilder.CreateCollection();
|
||||
var mappers = Current.Container.GetInstance<IMapperCollection>();
|
||||
databaseFactory = new UmbracoDatabaseFactory(Constants.System.UmbracoConnectionName, GetDefaultSqlSyntaxProviders(logger), logger, mappers);
|
||||
databaseFactory = new UmbracoDatabaseFactory(Constants.System.UmbracoConnectionName, logger, new Lazy<IMapperCollection>(() => mappers));
|
||||
}
|
||||
|
||||
fileSystems = fileSystems ?? new FileSystems(Current.Container, logger);
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace Umbraco.Tests.TestHelpers
|
||||
Container.Register(factory => PublishedSnapshotService);
|
||||
Container.Register(factory => DefaultCultureAccessor);
|
||||
|
||||
Container.GetInstance<DataEditorCollectionBuilder>()
|
||||
Composition.GetCollectionBuilder<DataEditorCollectionBuilder>()
|
||||
.Clear()
|
||||
.Add(f => f.GetInstance<TypeLoader>().GetDataEditors());
|
||||
|
||||
@@ -85,10 +85,9 @@ namespace Umbraco.Tests.TestHelpers
|
||||
if (Options.Database == UmbracoTestOptions.Database.None)
|
||||
return TestObjects.GetDatabaseFactoryMock();
|
||||
|
||||
var sqlSyntaxProviders = new[] { new SqlCeSyntaxProvider() };
|
||||
var logger = f.GetInstance<ILogger>();
|
||||
var mappers = f.GetInstance<IMapperCollection>();
|
||||
var factory = new UmbracoDatabaseFactory(GetDbConnectionString(), GetDbProviderName(), sqlSyntaxProviders, logger, mappers);
|
||||
var factory = new UmbracoDatabaseFactory(GetDbConnectionString(), GetDbProviderName(), logger, new Lazy<IMapperCollection>(() => mappers));
|
||||
factory.ResetForTests();
|
||||
return factory;
|
||||
});
|
||||
|
||||
@@ -76,6 +76,8 @@ namespace Umbraco.Tests.Testing
|
||||
// test feature, and no test "base" class should be. only actual test feature classes
|
||||
// should be marked with that attribute.
|
||||
|
||||
protected Composition Composition { get; private set; }
|
||||
|
||||
protected IContainer Container { get; private set; }
|
||||
|
||||
protected UmbracoTestAttribute Options { get; private set; }
|
||||
@@ -116,6 +118,7 @@ namespace Umbraco.Tests.Testing
|
||||
Reset();
|
||||
|
||||
Container = Current.Container = ContainerFactory.Create();
|
||||
Composition = new Composition(Container, RuntimeLevel.Run);
|
||||
|
||||
TestObjects = new TestObjects(Container);
|
||||
|
||||
@@ -189,7 +192,7 @@ namespace Umbraco.Tests.Testing
|
||||
// web
|
||||
Container.Register(_ => Umbraco.Web.Composing.Current.UmbracoContextAccessor);
|
||||
Container.RegisterSingleton<PublishedRouter>();
|
||||
Container.RegisterCollectionBuilder<ContentFinderCollectionBuilder>();
|
||||
Composition.GetCollectionBuilder<ContentFinderCollectionBuilder>();
|
||||
Container.Register<IContentLastChanceFinder, TestLastChanceFinder>();
|
||||
Container.Register<IVariationContextAccessor, TestVariationContextAccessor>();
|
||||
}
|
||||
@@ -202,14 +205,14 @@ namespace Umbraco.Tests.Testing
|
||||
Container.RegisterSingleton(f => runtimeStateMock.Object);
|
||||
|
||||
// ah...
|
||||
Container.RegisterCollectionBuilder<ActionCollectionBuilder>();
|
||||
Container.RegisterCollectionBuilder<PropertyValueConverterCollectionBuilder>();
|
||||
Composition.GetCollectionBuilder<ActionCollectionBuilder>();
|
||||
Composition.GetCollectionBuilder<PropertyValueConverterCollectionBuilder>();
|
||||
Container.RegisterSingleton<IPublishedContentTypeFactory, PublishedContentTypeFactory>();
|
||||
|
||||
Container.RegisterSingleton<IMediaPathScheme, OriginalMediaPathScheme>();
|
||||
|
||||
// register empty content apps collection
|
||||
Container.RegisterCollectionBuilder<ContentAppDefinitionCollectionBuilder>();
|
||||
Composition.GetCollectionBuilder<ContentAppDefinitionCollectionBuilder>();
|
||||
}
|
||||
|
||||
protected virtual void ComposeCacheHelper()
|
||||
@@ -307,20 +310,17 @@ namespace Umbraco.Tests.Testing
|
||||
Container.RegisterSingleton<IPublishedModelFactory, NoopPublishedModelFactory>();
|
||||
|
||||
// register application stuff (database factory & context, services...)
|
||||
Container.RegisterCollectionBuilder<MapperCollectionBuilder>()
|
||||
.AddCore();
|
||||
Composition.GetCollectionBuilder<MapperCollectionBuilder>()
|
||||
.AddCoreMappers();
|
||||
|
||||
Container.RegisterSingleton<IEventMessagesFactory>(_ => new TransientEventMessagesFactory());
|
||||
var sqlSyntaxProviders = TestObjects.GetDefaultSqlSyntaxProviders(Logger);
|
||||
Container.RegisterSingleton<ISqlSyntaxProvider>(_ => sqlSyntaxProviders.OfType<SqlCeSyntaxProvider>().First());
|
||||
Container.RegisterSingleton<IUmbracoDatabaseFactory>(f => new UmbracoDatabaseFactory(
|
||||
Constants.System.UmbracoConnectionName,
|
||||
sqlSyntaxProviders,
|
||||
Logger,
|
||||
Mock.Of<IMapperCollection>()));
|
||||
new Lazy<IMapperCollection>(() => Mock.Of<IMapperCollection>())));
|
||||
Container.RegisterSingleton(f => f.TryGetInstance<IUmbracoDatabaseFactory>().SqlContext);
|
||||
|
||||
Container.RegisterCollectionBuilder<UrlSegmentProviderCollectionBuilder>(); // empty
|
||||
Composition.GetCollectionBuilder<UrlSegmentProviderCollectionBuilder>(); // empty
|
||||
|
||||
Container.RegisterSingleton(factory
|
||||
=> TestObjects.GetScopeProvider(factory.TryGetInstance<ILogger>(), factory.TryGetInstance<FileSystems>(), factory.TryGetInstance<IUmbracoDatabaseFactory>()));
|
||||
@@ -333,12 +333,11 @@ namespace Umbraco.Tests.Testing
|
||||
Container.RegisterSingleton<ISectionService, SectionService>();
|
||||
|
||||
// somehow property editor ends up wanting this
|
||||
Container.RegisterCollectionBuilder<ManifestValueValidatorCollectionBuilder>();
|
||||
Composition.GetCollectionBuilder<ManifestValueValidatorCollectionBuilder>();
|
||||
Container.RegisterSingleton<ManifestParser>();
|
||||
|
||||
// note - don't register collections, use builders
|
||||
Container.RegisterCollectionBuilder<DataEditorCollectionBuilder>();
|
||||
var temp = Container.GetInstance<DataEditorCollectionBuilder>();
|
||||
Composition.GetCollectionBuilder<DataEditorCollectionBuilder>();
|
||||
Container.RegisterSingleton<PropertyEditorCollection>();
|
||||
Container.RegisterSingleton<ParameterEditorCollection>();
|
||||
}
|
||||
|
||||
@@ -7,10 +7,6 @@ namespace Umbraco.Web.Actions
|
||||
{
|
||||
internal class ActionCollectionBuilder : LazyCollectionBuilderBase<ActionCollectionBuilder, ActionCollection, IAction>
|
||||
{
|
||||
public ActionCollectionBuilder(IContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
protected override ActionCollectionBuilder This => this;
|
||||
|
||||
protected override IEnumerable<IAction> CreateItems()
|
||||
|
||||
@@ -9,10 +9,6 @@ namespace Umbraco.Web.ContentApps
|
||||
{
|
||||
public class ContentAppDefinitionCollectionBuilder : OrderedCollectionBuilderBase<ContentAppDefinitionCollectionBuilder, ContentAppDefinitionCollection, IContentAppDefinition>
|
||||
{
|
||||
public ContentAppDefinitionCollectionBuilder(IContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
protected override ContentAppDefinitionCollectionBuilder This => this;
|
||||
|
||||
// need to inject dependencies in the collection, so override creation
|
||||
|
||||
@@ -4,10 +4,6 @@ namespace Umbraco.Web.Editors
|
||||
{
|
||||
internal class EditorValidatorCollectionBuilder : LazyCollectionBuilderBase<EditorValidatorCollectionBuilder, EditorValidatorCollection, IEditorValidator>
|
||||
{
|
||||
public EditorValidatorCollectionBuilder(IContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
protected override EditorValidatorCollectionBuilder This => this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,6 @@ namespace Umbraco.Web.HealthCheck
|
||||
{
|
||||
internal class HealthCheckNotificationMethodCollectionBuilder : LazyCollectionBuilderBase<HealthCheckNotificationMethodCollectionBuilder, HealthCheckNotificationMethodCollection, IHealthCheckNotificationMethod>
|
||||
{
|
||||
public HealthCheckNotificationMethodCollectionBuilder(IContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
protected override HealthCheckNotificationMethodCollectionBuilder This => this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,6 @@ namespace Umbraco.Web.HealthCheck
|
||||
{
|
||||
public class HealthCheckCollectionBuilder : LazyCollectionBuilderBase<HealthCheckCollectionBuilder, HealthCheckCollection, HealthCheck>
|
||||
{
|
||||
public HealthCheckCollectionBuilder(IContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
protected override HealthCheckCollectionBuilder This => this;
|
||||
|
||||
// note: in v7 they were per-request, not sure why?
|
||||
|
||||
@@ -4,10 +4,6 @@ namespace Umbraco.Web.Mvc
|
||||
{
|
||||
public class FilteredControllerFactoryCollectionBuilder : OrderedCollectionBuilderBase<FilteredControllerFactoryCollectionBuilder, FilteredControllerFactoryCollection, IFilteredControllerFactory>
|
||||
{
|
||||
public FilteredControllerFactoryCollectionBuilder(IContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
protected override FilteredControllerFactoryCollectionBuilder This => this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,6 @@ namespace Umbraco.Web.Routing
|
||||
{
|
||||
public class ContentFinderCollectionBuilder : OrderedCollectionBuilderBase<ContentFinderCollectionBuilder, ContentFinderCollection, IContentFinder>
|
||||
{
|
||||
public ContentFinderCollectionBuilder(IContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
protected override ContentFinderCollectionBuilder This => this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,6 @@ namespace Umbraco.Web.Routing
|
||||
{
|
||||
public class UrlProviderCollectionBuilder : OrderedCollectionBuilderBase<UrlProviderCollectionBuilder, UrlProviderCollection, IUrlProvider>
|
||||
{
|
||||
public UrlProviderCollectionBuilder(IContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
protected override UrlProviderCollectionBuilder This => this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Web;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Components;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
@@ -51,21 +52,23 @@ namespace Umbraco.Web.Runtime
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Compose(IContainer container)
|
||||
public override void Compose(Composition composition)
|
||||
{
|
||||
base.Compose(composition);
|
||||
|
||||
var container = composition.Container;
|
||||
|
||||
// some components may want to initialize with the UmbracoApplicationBase
|
||||
// well, they should not - we should not do this
|
||||
// TODO remove this eventually.
|
||||
container.RegisterInstance(_umbracoApplication);
|
||||
base.Compose(container);
|
||||
}
|
||||
|
||||
container.Register<UmbracoInjectedModule>();
|
||||
#region Getters
|
||||
|
||||
// replace CoreRuntime's IProfiler registration
|
||||
container.RegisterSingleton(_ => _webProfiler);
|
||||
protected override IProfiler GetProfiler() => new WebProfiler();
|
||||
|
||||
// replace CoreRuntime's CacheHelper registration
|
||||
container.RegisterSingleton(_ => new CacheHelper(
|
||||
protected override CacheHelper GetAppCaches() => new CacheHelper(
|
||||
// we need to have the dep clone runtime cache provider to ensure
|
||||
// all entities are cached properly (cloned in and cloned out)
|
||||
new DeepCloneRuntimeCacheProvider(new HttpRuntimeCacheProvider(HttpRuntime.Cache)),
|
||||
@@ -75,26 +78,7 @@ namespace Umbraco.Web.Runtime
|
||||
new IsolatedRuntimeCache(type =>
|
||||
// we need to have the dep clone runtime cache provider to ensure
|
||||
// all entities are cached properly (cloned in and cloned out)
|
||||
new DeepCloneRuntimeCacheProvider(new ObjectCacheRuntimeCacheProvider()))));
|
||||
|
||||
container.RegisterSingleton<IHttpContextAccessor, AspNetHttpContextAccessor>(); // required for hybrid accessors
|
||||
}
|
||||
|
||||
#region Getters
|
||||
|
||||
//protected override IProfiler GetProfiler() => new WebProfiler();
|
||||
|
||||
//protected override CacheHelper GetApplicationCache() => new CacheHelper(
|
||||
// // we need to have the dep clone runtime cache provider to ensure
|
||||
// // all entities are cached properly (cloned in and cloned out)
|
||||
// new DeepCloneRuntimeCacheProvider(new HttpRuntimeCacheProvider(HttpRuntime.Cache)),
|
||||
// new StaticCacheProvider(),
|
||||
// // we need request based cache when running in web-based context
|
||||
// new HttpRequestCacheProvider(),
|
||||
// new IsolatedRuntimeCache(type =>
|
||||
// // we need to have the dep clone runtime cache provider to ensure
|
||||
// // all entities are cached properly (cloned in and cloned out)
|
||||
// new DeepCloneRuntimeCacheProvider(new ObjectCacheRuntimeCacheProvider())));
|
||||
new DeepCloneRuntimeCacheProvider(new ObjectCacheRuntimeCacheProvider())));
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -64,109 +64,115 @@ namespace Umbraco.Web.Runtime
|
||||
{
|
||||
base.Compose(composition);
|
||||
|
||||
composition.Container.ComposeWebMappingProfiles();
|
||||
var container = composition.Container;
|
||||
|
||||
container.Register<UmbracoInjectedModule>();
|
||||
|
||||
container.RegisterSingleton<IHttpContextAccessor, AspNetHttpContextAccessor>(); // required for hybrid accessors
|
||||
|
||||
container.ComposeWebMappingProfiles();
|
||||
|
||||
//register the install components
|
||||
//NOTE: i tried to not have these registered if we weren't installing or upgrading but post install when the site restarts
|
||||
//it still needs to use the install controller so we can't do that
|
||||
composition.Container.ComposeInstaller();
|
||||
container.ComposeInstaller();
|
||||
|
||||
// register membership stuff
|
||||
composition.Container.Register(factory => Core.Security.MembershipProviderExtensions.GetMembersMembershipProvider());
|
||||
composition.Container.Register(factory => Roles.Enabled ? Roles.Provider : new MembersRoleProvider(factory.GetInstance<IMemberService>()));
|
||||
composition.Container.Register<MembershipHelper>();
|
||||
container.Register(factory => Core.Security.MembershipProviderExtensions.GetMembersMembershipProvider());
|
||||
container.Register(factory => Roles.Enabled ? Roles.Provider : new MembersRoleProvider(factory.GetInstance<IMemberService>()));
|
||||
container.Register<MembershipHelper>();
|
||||
|
||||
// register accessors for cultures
|
||||
composition.Container.RegisterSingleton<IDefaultCultureAccessor, DefaultCultureAccessor>();
|
||||
composition.Container.RegisterSingleton<IVariationContextAccessor, HttpContextVariationContextAccessor>();
|
||||
container.RegisterSingleton<IDefaultCultureAccessor, DefaultCultureAccessor>();
|
||||
container.RegisterSingleton<IVariationContextAccessor, HttpContextVariationContextAccessor>();
|
||||
|
||||
var typeLoader = composition.Container.GetInstance<TypeLoader>();
|
||||
var logger = composition.Container.GetInstance<ILogger>();
|
||||
var proflog = composition.Container.GetInstance<ProfilingLogger>();
|
||||
var typeLoader = container.GetInstance<TypeLoader>();
|
||||
var logger = container.GetInstance<ILogger>();
|
||||
var proflog = container.GetInstance<ProfilingLogger>();
|
||||
|
||||
// register the http context and umbraco context accessors
|
||||
// we *should* use the HttpContextUmbracoContextAccessor, however there are cases when
|
||||
// we have no http context, eg when booting Umbraco or in background threads, so instead
|
||||
// let's use an hybrid accessor that can fall back to a ThreadStatic context.
|
||||
composition.Container.RegisterSingleton<IUmbracoContextAccessor, HybridUmbracoContextAccessor>();
|
||||
container.RegisterSingleton<IUmbracoContextAccessor, HybridUmbracoContextAccessor>();
|
||||
|
||||
// register a per-request HttpContextBase object
|
||||
// is per-request so only one wrapper is created per request
|
||||
composition.Container.Register<HttpContextBase>(factory => new HttpContextWrapper(factory.GetInstance<IHttpContextAccessor>().HttpContext), Lifetime.Request);
|
||||
container.Register<HttpContextBase>(factory => new HttpContextWrapper(factory.GetInstance<IHttpContextAccessor>().HttpContext), Lifetime.Request);
|
||||
|
||||
// register the published snapshot accessor - the "current" published snapshot is in the umbraco context
|
||||
composition.Container.RegisterSingleton<IPublishedSnapshotAccessor, UmbracoContextPublishedSnapshotAccessor>();
|
||||
container.RegisterSingleton<IPublishedSnapshotAccessor, UmbracoContextPublishedSnapshotAccessor>();
|
||||
|
||||
// we should stop injecting UmbracoContext and always inject IUmbracoContextAccessor, however at the moment
|
||||
// there are tons of places (controllers...) which require UmbracoContext in their ctor - so let's register
|
||||
// a way to inject the UmbracoContext - and register it per-request to be more efficient
|
||||
//TODO: stop doing this
|
||||
composition.Container.Register(factory => factory.GetInstance<IUmbracoContextAccessor>().UmbracoContext, Lifetime.Request);
|
||||
container.Register(factory => factory.GetInstance<IUmbracoContextAccessor>().UmbracoContext, Lifetime.Request);
|
||||
|
||||
// register the umbraco helper
|
||||
composition.Container.RegisterSingleton<UmbracoHelper>();
|
||||
container.RegisterSingleton<UmbracoHelper>();
|
||||
|
||||
// register distributed cache
|
||||
composition.Container.RegisterSingleton(f => new DistributedCache());
|
||||
container.RegisterSingleton(f => new DistributedCache());
|
||||
|
||||
// replace some services
|
||||
composition.Container.RegisterSingleton<IEventMessagesFactory, DefaultEventMessagesFactory>();
|
||||
composition.Container.RegisterSingleton<IEventMessagesAccessor, HybridEventMessagesAccessor>();
|
||||
composition.Container.RegisterSingleton<IApplicationTreeService, ApplicationTreeService>();
|
||||
composition.Container.RegisterSingleton<ISectionService, SectionService>();
|
||||
container.RegisterSingleton<IEventMessagesFactory, DefaultEventMessagesFactory>();
|
||||
container.RegisterSingleton<IEventMessagesAccessor, HybridEventMessagesAccessor>();
|
||||
container.RegisterSingleton<IApplicationTreeService, ApplicationTreeService>();
|
||||
container.RegisterSingleton<ISectionService, SectionService>();
|
||||
|
||||
composition.Container.RegisterSingleton<IExamineManager>(factory => ExamineManager.Instance);
|
||||
container.RegisterSingleton<IExamineManager>(factory => ExamineManager.Instance);
|
||||
|
||||
// configure the container for web
|
||||
composition.Container.ConfigureForWeb();
|
||||
composition.Container.ComposeMvcControllers(typeLoader, GetType().Assembly);
|
||||
composition.Container.ComposeApiControllers(typeLoader, GetType().Assembly);
|
||||
container.ConfigureForWeb();
|
||||
container.ComposeMvcControllers(typeLoader, GetType().Assembly);
|
||||
container.ComposeApiControllers(typeLoader, GetType().Assembly);
|
||||
|
||||
composition.Container.RegisterCollectionBuilder<SearchableTreeCollectionBuilder>()
|
||||
composition.GetCollectionBuilder<SearchableTreeCollectionBuilder>()
|
||||
.Add(() => typeLoader.GetTypes<ISearchableTree>()); // fixme which searchable trees?!
|
||||
|
||||
composition.Container.RegisterCollectionBuilder<EditorValidatorCollectionBuilder>()
|
||||
composition.GetCollectionBuilder<EditorValidatorCollectionBuilder>()
|
||||
.Add(() => typeLoader.GetTypes<IEditorValidator>());
|
||||
|
||||
composition.Container.RegisterCollectionBuilder<TourFilterCollectionBuilder>();
|
||||
composition.GetCollectionBuilder<TourFilterCollectionBuilder>();
|
||||
|
||||
composition.Container.RegisterSingleton<UmbracoFeatures>();
|
||||
container.RegisterSingleton<UmbracoFeatures>();
|
||||
|
||||
// set the default RenderMvcController
|
||||
Current.DefaultRenderMvcControllerType = typeof(RenderMvcController); // fixme WRONG!
|
||||
|
||||
composition.Container.RegisterCollectionBuilder<ActionCollectionBuilder>()
|
||||
composition.GetCollectionBuilder<ActionCollectionBuilder>()
|
||||
.Add(() => typeLoader.GetTypes<IAction>());
|
||||
|
||||
var surfaceControllerTypes = new SurfaceControllerTypeCollection(typeLoader.GetSurfaceControllers());
|
||||
composition.Container.RegisterInstance(surfaceControllerTypes);
|
||||
container.RegisterInstance(surfaceControllerTypes);
|
||||
|
||||
var umbracoApiControllerTypes = new UmbracoApiControllerTypeCollection(typeLoader.GetUmbracoApiControllers());
|
||||
composition.Container.RegisterInstance(umbracoApiControllerTypes);
|
||||
container.RegisterInstance(umbracoApiControllerTypes);
|
||||
|
||||
// both TinyMceValueConverter (in Core) and RteMacroRenderingValueConverter (in Web) will be
|
||||
// discovered when CoreBootManager configures the converters. We HAVE to remove one of them
|
||||
// here because there cannot be two converters for one property editor - and we want the full
|
||||
// RteMacroRenderingValueConverter that converts macros, etc. So remove TinyMceValueConverter.
|
||||
// (the limited one, defined in Core, is there for tests) - same for others
|
||||
composition.Container.GetInstance<PropertyValueConverterCollectionBuilder>()
|
||||
container.GetInstance<PropertyValueConverterCollectionBuilder>()
|
||||
.Remove<TinyMceValueConverter>()
|
||||
.Remove<TextStringValueConverter>()
|
||||
.Remove<MarkdownEditorValueConverter>();
|
||||
|
||||
// add all known factories, devs can then modify this list on application
|
||||
// startup either by binding to events or in their own global.asax
|
||||
composition.Container.RegisterCollectionBuilder<FilteredControllerFactoryCollectionBuilder>()
|
||||
composition.GetCollectionBuilder<FilteredControllerFactoryCollectionBuilder>()
|
||||
.Append<RenderControllerFactory>();
|
||||
|
||||
composition.Container.RegisterCollectionBuilder<UrlProviderCollectionBuilder>()
|
||||
composition.GetCollectionBuilder<UrlProviderCollectionBuilder>()
|
||||
.Append<AliasUrlProvider>()
|
||||
.Append<DefaultUrlProvider>()
|
||||
.Append<CustomRouteUrlProvider>();
|
||||
|
||||
composition.Container.RegisterSingleton<IContentLastChanceFinder, ContentFinderByLegacy404>();
|
||||
container.RegisterSingleton<IContentLastChanceFinder, ContentFinderByLegacy404>();
|
||||
|
||||
composition.Container.RegisterCollectionBuilder<ContentFinderCollectionBuilder>()
|
||||
composition.GetCollectionBuilder<ContentFinderCollectionBuilder>()
|
||||
// all built-in finders in the correct order,
|
||||
// devs can then modify this list on application startup
|
||||
.Append<ContentFinderByPageIdQuery>()
|
||||
@@ -176,32 +182,32 @@ namespace Umbraco.Web.Runtime
|
||||
.Append<ContentFinderByUrlAlias>()
|
||||
.Append<ContentFinderByRedirectUrl>();
|
||||
|
||||
composition.Container.RegisterSingleton<ISiteDomainHelper, SiteDomainHelper>();
|
||||
container.RegisterSingleton<ISiteDomainHelper, SiteDomainHelper>();
|
||||
|
||||
composition.Container.RegisterSingleton<ICultureDictionaryFactory, DefaultCultureDictionaryFactory>();
|
||||
container.RegisterSingleton<ICultureDictionaryFactory, DefaultCultureDictionaryFactory>();
|
||||
|
||||
// register *all* checks, except those marked [HideFromTypeFinder] of course
|
||||
composition.Container.RegisterCollectionBuilder<HealthCheckCollectionBuilder>()
|
||||
composition.GetCollectionBuilder<HealthCheckCollectionBuilder>()
|
||||
.Add(() => typeLoader.GetTypes<HealthCheck.HealthCheck>());
|
||||
|
||||
composition.Container.RegisterCollectionBuilder<HealthCheckNotificationMethodCollectionBuilder>()
|
||||
composition.GetCollectionBuilder<HealthCheckNotificationMethodCollectionBuilder>()
|
||||
.Add(() => typeLoader.GetTypes<HealthCheck.NotificationMethods.IHealthCheckNotificationMethod>());
|
||||
|
||||
// auto-register views
|
||||
composition.Container.RegisterAuto(typeof(UmbracoViewPage<>));
|
||||
container.RegisterAuto(typeof(UmbracoViewPage<>));
|
||||
|
||||
// register published router
|
||||
composition.Container.RegisterSingleton<PublishedRouter>();
|
||||
composition.Container.Register(_ => UmbracoConfig.For.UmbracoSettings().WebRouting);
|
||||
container.RegisterSingleton<PublishedRouter>();
|
||||
container.Register(_ => UmbracoConfig.For.UmbracoSettings().WebRouting);
|
||||
|
||||
// register preview SignalR hub
|
||||
composition.Container.RegisterSingleton(_ => GlobalHost.ConnectionManager.GetHubContext<PreviewHub>());
|
||||
container.RegisterSingleton(_ => GlobalHost.ConnectionManager.GetHubContext<PreviewHub>());
|
||||
|
||||
// register properties fallback
|
||||
composition.Container.RegisterSingleton<IPublishedValueFallback, PublishedValueFallback>();
|
||||
container.RegisterSingleton<IPublishedValueFallback, PublishedValueFallback>();
|
||||
|
||||
// register known content apps
|
||||
composition.Container.RegisterCollectionBuilder<ContentAppDefinitionCollectionBuilder>()
|
||||
composition.GetCollectionBuilder<ContentAppDefinitionCollectionBuilder>()
|
||||
.Append<ListViewContentAppDefinition>()
|
||||
.Append<ContentEditorContentAppDefinition>()
|
||||
.Append<ContentInfoContentAppDefinition>();
|
||||
|
||||
@@ -1,24 +1,10 @@
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Trees;
|
||||
|
||||
namespace Umbraco.Web.Search
|
||||
{
|
||||
internal class SearchableTreeCollectionBuilder : LazyCollectionBuilderBase<SearchableTreeCollectionBuilder, SearchableTreeCollection, ISearchableTree>
|
||||
{
|
||||
private readonly IApplicationTreeService _treeService;
|
||||
|
||||
public SearchableTreeCollectionBuilder(IContainer container, IApplicationTreeService treeService)
|
||||
: base(container)
|
||||
{
|
||||
_treeService = treeService;
|
||||
}
|
||||
|
||||
protected override SearchableTreeCollectionBuilder This => this;
|
||||
|
||||
public override SearchableTreeCollection CreateCollection()
|
||||
{
|
||||
return new SearchableTreeCollection(CreateItems(), _treeService);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,13 +14,6 @@ namespace Umbraco.Web.Tour
|
||||
{
|
||||
private readonly HashSet<BackOfficeTourFilter> _instances = new HashSet<BackOfficeTourFilter>();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TourFilterCollectionBuilder"/> class.
|
||||
/// </summary>
|
||||
public TourFilterCollectionBuilder(IContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IEnumerable<BackOfficeTourFilter> CreateItems(/*params object[] args*/)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user