51 lines
1.1 KiB
C#
51 lines
1.1 KiB
C#
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<ConcurrentStack<IScopeContext>> _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<IScopeContext>();
|
|
|
|
_stack.Value.Push(scope);
|
|
}
|
|
}
|
|
}
|