Bugfix FileSystems vs Scopes
This commit is contained in:
@@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Composing;
|
||||
@@ -29,6 +30,13 @@ namespace Umbraco.Core.IO
|
||||
private ShadowWrapper _masterPagesFileSystem;
|
||||
private ShadowWrapper _mvcViewsFileSystem;
|
||||
|
||||
// well-known file systems lazy initialization
|
||||
private object _wkfsLock = new object();
|
||||
private bool _wkfsInitialized;
|
||||
private object _wkfsObject;
|
||||
|
||||
private MediaFileSystem _mediaFileSystem;
|
||||
|
||||
#region Constructor
|
||||
|
||||
// DI wants a public ctor
|
||||
@@ -37,7 +45,6 @@ namespace Umbraco.Core.IO
|
||||
{
|
||||
_config = (FileSystemProvidersSection)ConfigurationManager.GetSection("umbracoConfiguration/FileSystemProviders");
|
||||
_logger = logger;
|
||||
CreateWellKnownFileSystems();
|
||||
}
|
||||
|
||||
// for tests only, totally unsafe
|
||||
@@ -46,25 +53,95 @@ namespace Umbraco.Core.IO
|
||||
_wrappers.Clear();
|
||||
_providerLookup.Clear();
|
||||
_filesystems.Clear();
|
||||
CreateWellKnownFileSystems();
|
||||
Volatile.Write(ref _wkfsInitialized, false);
|
||||
}
|
||||
|
||||
internal Func<bool> IsScoped { get; set; }
|
||||
internal Func<bool> IsScoped { get; set; } = () => false;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Well-Known FileSystems
|
||||
|
||||
public IFileSystem MacroPartialsFileSystem => _macroPartialFileSystem;
|
||||
public IFileSystem PartialViewsFileSystem => _partialViewsFileSystem;
|
||||
public IFileSystem StylesheetsFileSystem => _stylesheetsFileSystem;
|
||||
public IFileSystem ScriptsFileSystem => _scriptsFileSystem;
|
||||
public IFileSystem XsltFileSystem => _xsltFileSystem;
|
||||
public IFileSystem MasterPagesFileSystem => _masterPagesFileSystem; // fixme - see 7.6?!
|
||||
public IFileSystem MvcViewsFileSystem => _mvcViewsFileSystem;
|
||||
public MediaFileSystem MediaFileSystem { get; private set; }
|
||||
public IFileSystem MacroPartialsFileSystem
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Volatile.Read(ref _wkfsInitialized) == false) EnsureWellKnownFileSystems();
|
||||
return _macroPartialFileSystem;
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateWellKnownFileSystems()
|
||||
public IFileSystem PartialViewsFileSystem
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Volatile.Read(ref _wkfsInitialized) == false) EnsureWellKnownFileSystems();
|
||||
return _partialViewsFileSystem;
|
||||
}
|
||||
}
|
||||
|
||||
public IFileSystem StylesheetsFileSystem
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Volatile.Read(ref _wkfsInitialized) == false) EnsureWellKnownFileSystems();
|
||||
return _stylesheetsFileSystem;
|
||||
}
|
||||
}
|
||||
|
||||
public IFileSystem ScriptsFileSystem
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Volatile.Read(ref _wkfsInitialized) == false) EnsureWellKnownFileSystems();
|
||||
return _scriptsFileSystem;
|
||||
}
|
||||
}
|
||||
|
||||
public IFileSystem XsltFileSystem
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Volatile.Read(ref _wkfsInitialized) == false) EnsureWellKnownFileSystems();
|
||||
return _xsltFileSystem;
|
||||
}
|
||||
}
|
||||
|
||||
public IFileSystem MasterPagesFileSystem
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Volatile.Read(ref _wkfsInitialized) == false) EnsureWellKnownFileSystems();
|
||||
return _masterPagesFileSystem;// fixme - see 7.6?!
|
||||
}
|
||||
}
|
||||
|
||||
public IFileSystem MvcViewsFileSystem
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Volatile.Read(ref _wkfsInitialized) == false) EnsureWellKnownFileSystems();
|
||||
return _mvcViewsFileSystem;
|
||||
}
|
||||
}
|
||||
|
||||
public MediaFileSystem MediaFileSystem
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Volatile.Read(ref _wkfsInitialized) == false) EnsureWellKnownFileSystems();
|
||||
return _mediaFileSystem;
|
||||
}
|
||||
}
|
||||
|
||||
private void EnsureWellKnownFileSystems()
|
||||
{
|
||||
LazyInitializer.EnsureInitialized(ref _wkfsObject, ref _wkfsInitialized, ref _wkfsLock, CreateWellKnownFileSystems);
|
||||
}
|
||||
|
||||
// need to return something to LazyInitializer.EnsureInitialized
|
||||
// but it does not really matter what we return - here, null
|
||||
private object CreateWellKnownFileSystems()
|
||||
{
|
||||
var macroPartialFileSystem = new PhysicalFileSystem(SystemDirectories.MacroPartials);
|
||||
var partialViewsFileSystem = new PhysicalFileSystem(SystemDirectories.PartialViews);
|
||||
@@ -74,16 +151,18 @@ namespace Umbraco.Core.IO
|
||||
var masterPagesFileSystem = new PhysicalFileSystem(SystemDirectories.Masterpages);
|
||||
var mvcViewsFileSystem = new PhysicalFileSystem(SystemDirectories.MvcViews);
|
||||
|
||||
_macroPartialFileSystem = new ShadowWrapper(macroPartialFileSystem, "Views/MacroPartials", IsScoped);
|
||||
_partialViewsFileSystem = new ShadowWrapper(partialViewsFileSystem, "Views/Partials", IsScoped);
|
||||
_stylesheetsFileSystem = new ShadowWrapper(stylesheetsFileSystem, "css", IsScoped);
|
||||
_scriptsFileSystem = new ShadowWrapper(scriptsFileSystem, "scripts", IsScoped);
|
||||
_xsltFileSystem = new ShadowWrapper(xsltFileSystem, "xslt", IsScoped);
|
||||
_masterPagesFileSystem = new ShadowWrapper(masterPagesFileSystem, "masterpages", IsScoped);
|
||||
_mvcViewsFileSystem = new ShadowWrapper(mvcViewsFileSystem, "Views", IsScoped);
|
||||
_macroPartialFileSystem = new ShadowWrapper(macroPartialFileSystem, "Views/MacroPartials", () => IsScoped());
|
||||
_partialViewsFileSystem = new ShadowWrapper(partialViewsFileSystem, "Views/Partials", () => IsScoped());
|
||||
_stylesheetsFileSystem = new ShadowWrapper(stylesheetsFileSystem, "css", () => IsScoped());
|
||||
_scriptsFileSystem = new ShadowWrapper(scriptsFileSystem, "scripts", () => IsScoped());
|
||||
_xsltFileSystem = new ShadowWrapper(xsltFileSystem, "xslt", () => IsScoped());
|
||||
_masterPagesFileSystem = new ShadowWrapper(masterPagesFileSystem, "masterpages", () => IsScoped());
|
||||
_mvcViewsFileSystem = new ShadowWrapper(mvcViewsFileSystem, "Views", () => IsScoped());
|
||||
|
||||
// filesystems obtained from GetFileSystemProvider are already wrapped and do not need to be wrapped again
|
||||
MediaFileSystem = GetFileSystemProvider<MediaFileSystem>();
|
||||
_mediaFileSystem = GetFileSystemProvider<MediaFileSystem>();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -215,7 +294,7 @@ namespace Umbraco.Core.IO
|
||||
// so we are double-wrapping here
|
||||
// could be optimized by having FileSystemWrapper inherit from ShadowWrapper, maybe
|
||||
var innerFs = GetUnderlyingFileSystemNoCache(alias, fallback);
|
||||
var shadowWrapper = new ShadowWrapper(innerFs, "typed/" + alias, IsScoped);
|
||||
var shadowWrapper = new ShadowWrapper(innerFs, "typed/" + alias, () => IsScoped());
|
||||
var fs = (IFileSystem) Activator.CreateInstance(typeof(TFileSystem), shadowWrapper);
|
||||
_wrappers.Add(shadowWrapper); // keeping a reference to the wrapper
|
||||
return fs;
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Umbraco.Core.IO
|
||||
{
|
||||
_innerFileSystem = innerFileSystem;
|
||||
_shadowPath = shadowPath;
|
||||
_isScoped = isScoped ?? (() => false);
|
||||
_isScoped = isScoped;
|
||||
}
|
||||
|
||||
internal void Shadow(Guid id)
|
||||
|
||||
@@ -12,12 +12,9 @@ namespace Umbraco.Core.Persistence.Migrations
|
||||
{
|
||||
public MigrationContext(IUmbracoDatabase database, ILogger logger)
|
||||
{
|
||||
if (database == null) throw new ArgumentNullException(nameof(database));
|
||||
if (logger == null) throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
Expressions = new Collection<IMigrationExpression>();
|
||||
Database = database;
|
||||
Logger = logger;
|
||||
Database = database ?? throw new ArgumentNullException(nameof(database));
|
||||
Logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
|
||||
public ICollection<IMigrationExpression> Expressions { get; set; }
|
||||
|
||||
@@ -31,6 +31,8 @@ namespace Umbraco.Core.Scoping
|
||||
|
||||
// take control of the FileSystems
|
||||
_fileSystems.IsScoped = () => AmbientScope != null && AmbientScope.ScopedFileSystems;
|
||||
|
||||
_scopeReference = new ScopeReference(this);
|
||||
}
|
||||
|
||||
static ScopeProvider()
|
||||
@@ -230,7 +232,7 @@ namespace Umbraco.Core.Scoping
|
||||
|
||||
internal const string ContextItemKey = "Umbraco.Core.Scoping.ScopeContext";
|
||||
|
||||
internal static ScopeContext AmbientContextStatic
|
||||
public ScopeContext AmbientContext
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -251,9 +253,6 @@ namespace Umbraco.Core.Scoping
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ScopeContext AmbientContext => AmbientContextStatic;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Ambient Scope
|
||||
@@ -262,10 +261,9 @@ namespace Umbraco.Core.Scoping
|
||||
internal const string ScopeRefItemKey = "Umbraco.Core.Scoping.ScopeReference";
|
||||
|
||||
// only 1 instance which can be disposed and disposed again
|
||||
// fixme - more weird static - we should try to get rid of all static & use an accessor
|
||||
private static readonly ScopeReference StaticScopeReference = new ScopeReference(new ScopeProvider(null, null, null));
|
||||
private readonly ScopeReference _scopeReference;
|
||||
|
||||
private static Scope AmbientScopeStatic
|
||||
public Scope AmbientScope
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -283,19 +281,12 @@ namespace Umbraco.Core.Scoping
|
||||
|
||||
// set http/call context
|
||||
if (value.CallContext == false && SetHttpContextObject(ScopeItemKey, value, false))
|
||||
SetHttpContextObject(ScopeRefItemKey, StaticScopeReference);
|
||||
SetHttpContextObject(ScopeRefItemKey, _scopeReference);
|
||||
else
|
||||
SetCallContextObject(ScopeItemKey, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Scope AmbientScope
|
||||
{
|
||||
get => AmbientScopeStatic;
|
||||
set => AmbientScopeStatic = value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void SetAmbient(Scope scope, ScopeContext context = null)
|
||||
@@ -315,7 +306,7 @@ namespace Umbraco.Core.Scoping
|
||||
|
||||
if (scope.CallContext == false && SetHttpContextObject(ScopeItemKey, scope, false))
|
||||
{
|
||||
SetHttpContextObject(ScopeRefItemKey, StaticScopeReference);
|
||||
SetHttpContextObject(ScopeRefItemKey, _scopeReference);
|
||||
SetHttpContextObject(ContextItemKey, context);
|
||||
}
|
||||
else
|
||||
@@ -410,7 +401,7 @@ namespace Umbraco.Core.Scoping
|
||||
var scope = AmbientScope as Scope;
|
||||
scope?.Reset();
|
||||
|
||||
StaticScopeReference.Dispose();
|
||||
_scopeReference.Dispose();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
Reference in New Issue
Block a user