diff --git a/src/Umbraco.Abstractions/Scoping/IScopeContext.cs b/src/Umbraco.Abstractions/Scoping/IScopeContext.cs
index 0a267e67e2..719cc5f0ad 100644
--- a/src/Umbraco.Abstractions/Scoping/IScopeContext.cs
+++ b/src/Umbraco.Abstractions/Scoping/IScopeContext.cs
@@ -8,7 +8,7 @@ namespace Umbraco.Core.Scoping
/// A scope context can enlist objects that will be attached to the scope, and available
/// for the duration of the scope. In addition, it can enlist actions, that will run when the
/// scope is exiting, and after the database transaction has been committed.
- public interface IScopeContext
+ public interface IScopeContext : IInstanceIdentifiable
{
///
/// Enlists an action.
@@ -46,5 +46,7 @@ namespace Umbraco.Core.Scoping
/// The object unique identifier.
/// The enlisted object, if any, else the default value.
T GetEnlisted(string key);
+
+ void ScopeExit(bool completed);
}
}
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index 22b5230e54..7adc7fd0ee 100755
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -155,7 +155,6 @@
-
@@ -215,12 +214,6 @@
-
-
-
-
-
-
diff --git a/src/Umbraco.Core/Events/QueuingEventDispatcher.cs b/src/Umbraco.Infrastructure/Events/QueuingEventDispatcher.cs
similarity index 71%
rename from src/Umbraco.Core/Events/QueuingEventDispatcher.cs
rename to src/Umbraco.Infrastructure/Events/QueuingEventDispatcher.cs
index 88b527e753..6260aaa176 100644
--- a/src/Umbraco.Core/Events/QueuingEventDispatcher.cs
+++ b/src/Umbraco.Infrastructure/Events/QueuingEventDispatcher.cs
@@ -1,4 +1,5 @@
-using Umbraco.Core.Composing;
+using Umbraco.Composing;
+using Umbraco.Core.Composing;
using Umbraco.Core.IO;
namespace Umbraco.Core.Events
@@ -7,11 +8,14 @@ namespace Umbraco.Core.Events
/// An IEventDispatcher that queues events, and raise them when the scope
/// exits and has been completed.
///
- internal class QueuingEventDispatcher : QueuingEventDispatcherBase
+ public class QueuingEventDispatcher : QueuingEventDispatcherBase
{
- public QueuingEventDispatcher()
+ private readonly IMediaFileSystem _mediaFileSystem;
+ public QueuingEventDispatcher(IMediaFileSystem mediaFileSystem)
: base(true)
- { }
+ {
+ _mediaFileSystem = mediaFileSystem;
+ }
protected override void ScopeExitCompleted()
{
@@ -28,13 +32,11 @@ namespace Umbraco.Core.Events
// but then where should it be (without making things too complicated)?
var delete = e.Args as IDeletingMediaFilesEventArgs;
if (delete != null && delete.MediaFilesToDelete.Count > 0)
- MediaFileSystem.DeleteMediaFiles(delete.MediaFilesToDelete);
+ _mediaFileSystem.DeleteMediaFiles(delete.MediaFilesToDelete);
}
}
- private IMediaFileSystem _mediaFileSystem;
- // TODO: inject
- private IMediaFileSystem MediaFileSystem => _mediaFileSystem ?? (_mediaFileSystem = Current.MediaFileSystem);
+
}
}
diff --git a/src/Umbraco.Infrastructure/Scoping/CallContext.cs b/src/Umbraco.Infrastructure/Scoping/CallContext.cs
new file mode 100644
index 0000000000..7b256434cd
--- /dev/null
+++ b/src/Umbraco.Infrastructure/Scoping/CallContext.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Concurrent;
+using System.Threading;
+
+namespace Umbraco.Core.Scoping
+{
+ ///
+ /// Provides a way to set contextual data that flows with the call and
+ /// async context of a test or invocation.
+ ///
+ public static class CallContext
+ {
+ private static readonly ConcurrentDictionary _state = new ConcurrentDictionary();
+
+ ///
+ /// Stores a given object and associates it with the specified name.
+ ///
+ /// The name with which to associate the new item in the call context.
+ /// The object to store in the call context.
+ public static void SetData(string name, Guid? data)
+ {
+ _state[name + Thread.CurrentThread.ManagedThreadId] = data;
+ }
+
+
+ ///
+ /// Retrieves an object with the specified name from the .
+ ///
+ /// The name of the item in the call context.
+ /// The object in the call context associated with the specified name, or if not found.
+ public static Guid? GetData(string name)
+ {
+ return _state.TryGetValue(name + Thread.CurrentThread.ManagedThreadId, out var data) ? data : null;
+ }
+
+ public static bool RemoveData(string name)
+ {
+ return _state.TryRemove(name+ Thread.CurrentThread.ManagedThreadId, out _);
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Scoping/IScopeAccessor.cs b/src/Umbraco.Infrastructure/Scoping/IScopeAccessor.cs
similarity index 100%
rename from src/Umbraco.Core/Scoping/IScopeAccessor.cs
rename to src/Umbraco.Infrastructure/Scoping/IScopeAccessor.cs
diff --git a/src/Umbraco.Core/Scoping/Scope.cs b/src/Umbraco.Infrastructure/Scoping/Scope.cs
similarity index 92%
rename from src/Umbraco.Core/Scoping/Scope.cs
rename to src/Umbraco.Infrastructure/Scoping/Scope.cs
index 3eabfbca9b..8f7a0bf958 100644
--- a/src/Umbraco.Core/Scoping/Scope.cs
+++ b/src/Umbraco.Infrastructure/Scoping/Scope.cs
@@ -2,6 +2,7 @@
using System.Data;
using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
+using Umbraco.Core.Configuration;
using Umbraco.Core.Events;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
@@ -16,6 +17,8 @@ namespace Umbraco.Core.Scoping
internal class Scope : IScope
{
private readonly ScopeProvider _scopeProvider;
+ private readonly ICoreDebug _coreDebug;
+ private readonly IMediaFileSystem _mediaFileSystem;
private readonly ILogger _logger;
private readonly ITypeFinder _typeFinder;
@@ -36,7 +39,9 @@ namespace Umbraco.Core.Scoping
// initializes a new scope
private Scope(ScopeProvider scopeProvider,
- ILogger logger, ITypeFinder typeFinder, FileSystems fileSystems, Scope parent, ScopeContext scopeContext, bool detachable,
+ ICoreDebug coreDebug,
+ IMediaFileSystem mediaFileSystem,
+ ILogger logger, ITypeFinder typeFinder, FileSystems fileSystems, Scope parent, IScopeContext scopeContext, bool detachable,
IsolationLevel isolationLevel = IsolationLevel.Unspecified,
RepositoryCacheMode repositoryCacheMode = RepositoryCacheMode.Unspecified,
IEventDispatcher eventDispatcher = null,
@@ -45,6 +50,8 @@ namespace Umbraco.Core.Scoping
bool autoComplete = false)
{
_scopeProvider = scopeProvider;
+ _coreDebug = coreDebug;
+ _mediaFileSystem = mediaFileSystem;
_logger = logger;
_typeFinder = typeFinder;
@@ -111,18 +118,22 @@ namespace Umbraco.Core.Scoping
// initializes a new scope
public Scope(ScopeProvider scopeProvider,
- ILogger logger, ITypeFinder typeFinder, FileSystems fileSystems, bool detachable, ScopeContext scopeContext,
+ ICoreDebug coreDebug,
+ IMediaFileSystem mediaFileSystem,
+ ILogger logger, ITypeFinder typeFinder, FileSystems fileSystems, bool detachable, IScopeContext scopeContext,
IsolationLevel isolationLevel = IsolationLevel.Unspecified,
RepositoryCacheMode repositoryCacheMode = RepositoryCacheMode.Unspecified,
IEventDispatcher eventDispatcher = null,
bool? scopeFileSystems = null,
bool callContext = false,
bool autoComplete = false)
- : this(scopeProvider, logger, typeFinder, fileSystems, null, scopeContext, detachable, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete)
+ : this(scopeProvider, coreDebug, mediaFileSystem, logger, typeFinder, fileSystems, null, scopeContext, detachable, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete)
{ }
// initializes a new scope in a nested scopes chain, with its parent
public Scope(ScopeProvider scopeProvider,
+ ICoreDebug coreDebug,
+ IMediaFileSystem mediaFileSystem,
ILogger logger, ITypeFinder typeFinder, FileSystems fileSystems, Scope parent,
IsolationLevel isolationLevel = IsolationLevel.Unspecified,
RepositoryCacheMode repositoryCacheMode = RepositoryCacheMode.Unspecified,
@@ -130,7 +141,7 @@ namespace Umbraco.Core.Scoping
bool? scopeFileSystems = null,
bool callContext = false,
bool autoComplete = false)
- : this(scopeProvider, logger, typeFinder, fileSystems, parent, null, false, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete)
+ : this(scopeProvider, coreDebug, mediaFileSystem, logger, typeFinder, fileSystems, parent, null, false, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete)
{ }
public Guid InstanceId { get; } = Guid.NewGuid();
@@ -194,10 +205,10 @@ namespace Umbraco.Core.Scoping
public Scope OrigScope { get; set; }
// the original context (when attaching a detachable scope)
- public ScopeContext OrigContext { get; set; }
+ public IScopeContext OrigContext { get; set; }
// the context (for attaching & detaching only)
- public ScopeContext Context { get; }
+ public IScopeContext Context { get; }
public IsolationLevel IsolationLevel
{
@@ -289,7 +300,7 @@ namespace Umbraco.Core.Scoping
{
EnsureNotDisposed();
if (ParentScope != null) return ParentScope.Events;
- return _eventDispatcher ?? (_eventDispatcher = new QueuingEventDispatcher());
+ return _eventDispatcher ?? (_eventDispatcher = new QueuingEventDispatcher(_mediaFileSystem));
}
}
@@ -484,8 +495,8 @@ namespace Umbraco.Core.Scoping
// caching config
// true if Umbraco.CoreDebug.LogUncompletedScope appSetting is set to "true"
- private static bool LogUncompletedScopes => (_logUncompletedScopes
- ?? (_logUncompletedScopes = Current.Configs.CoreDebug().LogUncompletedScopes)).Value;
+ private bool LogUncompletedScopes => (_logUncompletedScopes
+ ?? (_logUncompletedScopes = _coreDebug.LogUncompletedScopes)).Value;
///
public void ReadLock(params int[] lockIds) => Database.SqlContext.SqlSyntax.ReadLock(Database, lockIds);
diff --git a/src/Umbraco.Core/Scoping/ScopeContext.cs b/src/Umbraco.Infrastructure/Scoping/ScopeContext.cs
similarity index 100%
rename from src/Umbraco.Core/Scoping/ScopeContext.cs
rename to src/Umbraco.Infrastructure/Scoping/ScopeContext.cs
diff --git a/src/Umbraco.Core/Scoping/ScopeContextualBase.cs b/src/Umbraco.Infrastructure/Scoping/ScopeContextualBase.cs
similarity index 100%
rename from src/Umbraco.Core/Scoping/ScopeContextualBase.cs
rename to src/Umbraco.Infrastructure/Scoping/ScopeContextualBase.cs
diff --git a/src/Umbraco.Core/Scoping/ScopeProvider.cs b/src/Umbraco.Infrastructure/Scoping/ScopeProvider.cs
similarity index 91%
rename from src/Umbraco.Core/Scoping/ScopeProvider.cs
rename to src/Umbraco.Infrastructure/Scoping/ScopeProvider.cs
index c8b5b05f59..ef3afb2dac 100644
--- a/src/Umbraco.Core/Scoping/ScopeProvider.cs
+++ b/src/Umbraco.Infrastructure/Scoping/ScopeProvider.cs
@@ -1,13 +1,15 @@
using System;
using System.Collections.Generic;
using System.Data;
-using System.Runtime.Remoting.Messaging;
using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
+using Umbraco.Core.Configuration;
using Umbraco.Core.Events;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence;
+using Current = Umbraco.Composing.Current;
+
#if DEBUG_SCOPES
using System.Linq;
using System.Text;
@@ -24,15 +26,18 @@ namespace Umbraco.Core.Scoping
private readonly ITypeFinder _typeFinder;
private readonly IRequestCache _requestCache;
private readonly FileSystems _fileSystems;
+ private readonly ICoreDebug _coreDebug;
+ private readonly IMediaFileSystem _mediaFileSystem;
- public ScopeProvider(IUmbracoDatabaseFactory databaseFactory, FileSystems fileSystems, ILogger logger, ITypeFinder typeFinder, IRequestCache requestCache)
+ public ScopeProvider(IUmbracoDatabaseFactory databaseFactory, FileSystems fileSystems, ICoreDebug coreDebug, IMediaFileSystem mediaFileSystem, ILogger logger, ITypeFinder typeFinder, IRequestCache requestCache)
{
DatabaseFactory = databaseFactory;
_fileSystems = fileSystems;
+ _coreDebug = coreDebug;
+ _mediaFileSystem = mediaFileSystem;
_logger = logger;
_typeFinder = typeFinder;
_requestCache = requestCache;
-
// take control of the FileSystems
_fileSystems.IsScoped = () => AmbientScope != null && AmbientScope.ScopedFileSystems;
@@ -105,12 +110,12 @@ namespace Umbraco.Core.Scoping
private static T GetCallContextObject(string key)
where T : class
{
- var objectKey = CallContext.LogicalGetData(key).AsGuid();
- if (objectKey == Guid.Empty) return null;
+ var objectKey = CallContext.GetData(key);
+ if (objectKey is null) return null;
lock (StaticCallContextObjectsLock)
{
- if (StaticCallContextObjects.TryGetValue(objectKey, out object callContextObject))
+ if (StaticCallContextObjects.TryGetValue(objectKey.Value, out object callContextObject))
{
#if DEBUG_SCOPES
Current.Logger.Debug("Got " + typeof(T).Name + " Object " + objectKey.ToString("N").Substring(0, 8));
@@ -120,7 +125,7 @@ namespace Umbraco.Core.Scoping
}
// hard to inject into a static method :(
- Current.Logger.Warn("Missed {TypeName} Object {ObjectKey}", typeof(T).Name, objectKey.ToString("N").Substring(0, 8));
+ Current.Logger.Warn("Missed {TypeName} Object {ObjectKey}", typeof(T).Name, objectKey.Value.ToString("N").Substring(0, 8));
#if DEBUG_SCOPES
//Current.Logger.Debug("At:\r\n" + Head(Environment.StackTrace, 24));
#endif
@@ -136,7 +141,7 @@ namespace Umbraco.Core.Scoping
if (key == ScopeItemKey)
{
// first, null-register the existing value
- var ambientKey = CallContext.LogicalGetData(ScopeItemKey).AsGuid();
+ var ambientKey = CallContext.GetData(ScopeItemKey).AsGuid();
object o = null;
lock (StaticCallContextObjectsLock)
{
@@ -152,16 +157,16 @@ namespace Umbraco.Core.Scoping
#endif
if (value == null)
{
- var objectKey = CallContext.LogicalGetData(key).AsGuid();
- CallContext.FreeNamedDataSlot(key);
- if (objectKey == default) return;
+ var objectKey = CallContext.GetData(key);
+ CallContext.RemoveData(key);
+ if (objectKey is null) return;
lock (StaticCallContextObjectsLock)
{
#if DEBUG_SCOPES
Current.Logger.Debug("Remove Object " + objectKey.ToString("N").Substring(0, 8));
//Current.Logger.Debug("At:\r\n" + Head(Environment.StackTrace, 24));
#endif
- StaticCallContextObjects.Remove(objectKey);
+ StaticCallContextObjects.Remove(objectKey.Value);
}
}
else
@@ -178,7 +183,7 @@ namespace Umbraco.Core.Scoping
#endif
StaticCallContextObjects.Add(objectKey, value);
}
- CallContext.LogicalSetData(key, objectKey);
+ CallContext.SetData(key, objectKey);
}
}
@@ -228,13 +233,13 @@ namespace Umbraco.Core.Scoping
internal const string ContextItemKey = "Umbraco.Core.Scoping.ScopeContext";
- public ScopeContext AmbientContext
+ public IScopeContext AmbientContext
{
get
{
// try http context, fallback onto call context
- var value = GetHttpContextObject(ContextItemKey, false);
- return value ?? GetCallContextObject(ContextItemKey);
+ var value = GetHttpContextObject(ContextItemKey, false);
+ return value ?? GetCallContextObject(ContextItemKey);
}
set
{
@@ -285,7 +290,7 @@ namespace Umbraco.Core.Scoping
#endregion
- public void SetAmbient(Scope scope, ScopeContext context = null)
+ public void SetAmbient(Scope scope, IScopeContext context = null)
{
// clear all
SetHttpContextObject(ScopeItemKey, null, false);
@@ -319,7 +324,7 @@ namespace Umbraco.Core.Scoping
IEventDispatcher eventDispatcher = null,
bool? scopeFileSystems = null)
{
- return new Scope(this, _logger, _typeFinder, _fileSystems, true, null, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems);
+ return new Scope(this, _coreDebug, _mediaFileSystem, _logger, _typeFinder, _fileSystems, true, null, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems);
}
///
@@ -375,13 +380,13 @@ namespace Umbraco.Core.Scoping
{
var ambientContext = AmbientContext;
var newContext = ambientContext == null ? new ScopeContext() : null;
- var scope = new Scope(this, _logger, _typeFinder, _fileSystems, false, newContext, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete);
+ var scope = new Scope(this, _coreDebug, _mediaFileSystem, _logger, _typeFinder, _fileSystems, false, newContext, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete);
// assign only if scope creation did not throw!
SetAmbient(scope, newContext ?? ambientContext);
return scope;
}
- var nested = new Scope(this, _logger, _typeFinder, _fileSystems, ambientScope, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete);
+ var nested = new Scope(this, _coreDebug, _mediaFileSystem, _logger, _typeFinder, _fileSystems, ambientScope, isolationLevel, repositoryCacheMode, eventDispatcher, scopeFileSystems, callContext, autoComplete);
SetAmbient(nested, AmbientContext);
return nested;
}
diff --git a/src/Umbraco.Core/Scoping/ScopeReference.cs b/src/Umbraco.Infrastructure/Scoping/ScopeReference.cs
similarity index 100%
rename from src/Umbraco.Core/Scoping/ScopeReference.cs
rename to src/Umbraco.Infrastructure/Scoping/ScopeReference.cs
diff --git a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj
index f3fe26ca76..8e9baebbf0 100644
--- a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj
+++ b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj
@@ -28,18 +28,7 @@
<_UnmanagedRegistrationCache Remove="obj\Umbraco.Infrastructure.csproj.UnmanagedRegistration.cache" />
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -65,8 +54,11 @@
-
+
+
+
+
diff --git a/src/Umbraco.Tests/Components/ComponentTests.cs b/src/Umbraco.Tests/Components/ComponentTests.cs
index 880a1161fa..7166d17c3f 100644
--- a/src/Umbraco.Tests/Components/ComponentTests.cs
+++ b/src/Umbraco.Tests/Components/ComponentTests.cs
@@ -38,7 +38,9 @@ namespace Umbraco.Tests.Components
var typeFinder = new TypeFinder(logger);
var f = new UmbracoDatabaseFactory(logger, new Lazy(() => new MapperCollection(Enumerable.Empty())), TestHelper.GetConfigs(), TestHelper.DbProviderFactoryCreator, TestHelper.BulkSqlInsertProvider);
var fs = new FileSystems(mock.Object, logger, TestHelper.IOHelper, SettingsForTests.GenerateMockGlobalSettings());
- var p = new ScopeProvider(f, fs, logger, typeFinder, NoAppCache.Instance);
+ var coreDebug = Mock.Of();
+ var mediaFileSystem = Mock.Of();
+ var p = new ScopeProvider(f, fs, coreDebug, mediaFileSystem, logger, typeFinder, NoAppCache.Instance);
mock.Setup(x => x.GetInstance(typeof (ILogger))).Returns(logger);
mock.Setup(x => x.GetInstance(typeof (IProfilingLogger))).Returns(new ProfilingLogger(Mock.Of(), Mock.Of()));
diff --git a/src/Umbraco.Tests/Scoping/ScopeEventDispatcherTests.cs b/src/Umbraco.Tests/Scoping/ScopeEventDispatcherTests.cs
index 0824501059..56d8e320e1 100644
--- a/src/Umbraco.Tests/Scoping/ScopeEventDispatcherTests.cs
+++ b/src/Umbraco.Tests/Scoping/ScopeEventDispatcherTests.cs
@@ -337,7 +337,7 @@ namespace Umbraco.Tests.Scoping
{
var counter = 0;
IScope ambientScope = null;
- ScopeContext ambientContext = null;
+ IScopeContext ambientContext = null;
Guid value = Guid.Empty;
var scopeProvider = _testObjects.GetScopeProvider(Mock.Of()) as ScopeProvider;
diff --git a/src/Umbraco.Tests/Scoping/ScopeTests.cs b/src/Umbraco.Tests/Scoping/ScopeTests.cs
index b2a3b14800..d1f77d4ae0 100644
--- a/src/Umbraco.Tests/Scoping/ScopeTests.cs
+++ b/src/Umbraco.Tests/Scoping/ScopeTests.cs
@@ -8,7 +8,10 @@ using Umbraco.Core.Persistence;
using Umbraco.Core.Scoping;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.Testing;
-using ScopeProviderStatic = Umbraco.Core.Scoping.ScopeProvider;
+using CallContext = Umbraco.Core.Scoping.CallContext;
+
+//using CallContext = Umbraco.Core.Scoping.CallContext;
+
namespace Umbraco.Tests.Scoping
{
@@ -123,7 +126,7 @@ namespace Umbraco.Tests.Scoping
Assert.AreSame(scope, ((Scope) nested).ParentScope);
// it's moved over to call context
- var callContextKey = CallContext.LogicalGetData(ScopeProviderStatic.ScopeItemKey).AsGuid();
+ var callContextKey = CallContext.GetData(ScopeProvider.ScopeItemKey).AsGuid();
Assert.AreNotEqual(Guid.Empty, callContextKey);
// only if Core.DEBUG_SCOPES are defined
@@ -485,7 +488,7 @@ namespace Umbraco.Tests.Scoping
bool? completed = null;
IScope ambientScope = null;
- ScopeContext ambientContext = null;
+ IScopeContext ambientContext = null;
Assert.IsNull(scopeProvider.AmbientScope);
using (var scope = scopeProvider.CreateScope())
diff --git a/src/Umbraco.Tests/TestHelpers/TestObjects.cs b/src/Umbraco.Tests/TestHelpers/TestObjects.cs
index d5272f34b0..649c1e1f1e 100644
--- a/src/Umbraco.Tests/TestHelpers/TestObjects.cs
+++ b/src/Umbraco.Tests/TestHelpers/TestObjects.cs
@@ -248,7 +248,9 @@ namespace Umbraco.Tests.TestHelpers
typeFinder = typeFinder ?? new TypeFinder(logger);
fileSystems = fileSystems ?? new FileSystems(Current.Factory, logger, TestHelper.IOHelper, SettingsForTests.GenerateMockGlobalSettings());
- var scopeProvider = new ScopeProvider(databaseFactory, fileSystems, logger, typeFinder, NoAppCache.Instance);
+ var coreDebug = Current.Configs.CoreDebug();
+ var mediaFileSystem = Mock.Of();
+ var scopeProvider = new ScopeProvider(databaseFactory, fileSystems, coreDebug, mediaFileSystem, logger, typeFinder, NoAppCache.Instance);
return scopeProvider;
}
diff --git a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs
index 85ee03918c..ef8a0bc599 100644
--- a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs
+++ b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs
@@ -23,7 +23,6 @@ using Umbraco.Web.Security;
using Umbraco.Web.Routing;
using File = System.IO.File;
using Umbraco.Core.Composing;
-using Umbraco.Core.Hosting;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Scoping;
using Umbraco.Tests.Testing;
diff --git a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs
index c88fd353c1..8b6553ff80 100644
--- a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs
+++ b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Reflection;
+using System.Threading;
using System.Xml.Linq;
using Examine;
using Moq;
@@ -64,6 +65,7 @@ namespace Umbraco.Tests.Testing
/// provides all the necessary environment, through DI. Yes, DI is bad in tests - unit tests.
/// But it is OK in integration tests.
///
+ [Apartment(ApartmentState.STA)]
public abstract class UmbracoTestBase
{
// this class