using System.Collections.Concurrent; using Umbraco.Cms.Core.Scoping; namespace Umbraco.Cms.Infrastructure.Scoping; internal sealed class AmbientScopeContextStack : IAmbientScopeContextStack { private static Lock _lock = new(); private static AsyncLocal> _stack = new(); public IScopeContext? AmbientContext { get { lock (_lock) { if (_stack.Value?.TryPeek(out IScopeContext? ambientContext) ?? false) { return ambientContext; } return null; } } } public IScopeContext Pop() { lock (_lock) { if (_stack.Value?.TryPop(out IScopeContext? ambientContext) ?? false) { return ambientContext; } throw new InvalidOperationException("No AmbientContext was found."); } } public void Push(IScopeContext scope) { lock (_lock) { _stack.Value ??= new ConcurrentStack(); _stack.Value.Push(scope); } } }