2022-06-20 09:20:47 +02:00
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
|
|
|
|
|
namespace Umbraco.Cms.Infrastructure.Scoping
|
|
|
|
|
{
|
2025-07-21 08:32:54 +02:00
|
|
|
internal sealed class AmbientScopeStack : IAmbientScopeStack
|
2022-06-20 09:20:47 +02:00
|
|
|
{
|
2024-10-28 12:10:38 +01:00
|
|
|
private static Lock _lock = new();
|
2022-06-20 09:20:47 +02:00
|
|
|
private static AsyncLocal<ConcurrentStack<IScope>> _stack = new ();
|
|
|
|
|
|
|
|
|
|
public IScope? AmbientScope
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2024-10-28 12:10:38 +01:00
|
|
|
lock (_lock)
|
2022-06-20 09:20:47 +02:00
|
|
|
{
|
2024-10-28 12:10:38 +01:00
|
|
|
if (_stack.Value?.TryPeek(out IScope? ambientScope) ?? false)
|
|
|
|
|
{
|
|
|
|
|
return ambientScope;
|
|
|
|
|
}
|
2022-06-20 09:20:47 +02:00
|
|
|
|
2024-10-28 12:10:38 +01:00
|
|
|
return null;
|
|
|
|
|
}
|
2022-06-20 09:20:47 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IScope Pop()
|
|
|
|
|
{
|
2024-10-28 12:10:38 +01:00
|
|
|
lock (_lock)
|
2022-06-20 09:20:47 +02:00
|
|
|
{
|
|
|
|
|
|
2024-10-28 12:10:38 +01:00
|
|
|
|
|
|
|
|
if (_stack.Value?.TryPop(out IScope? ambientScope) ?? false)
|
|
|
|
|
{
|
|
|
|
|
return ambientScope;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
throw new InvalidOperationException("No AmbientScope was found.");
|
|
|
|
|
}
|
2022-06-20 09:20:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Push(IScope scope)
|
|
|
|
|
{
|
2024-10-28 12:10:38 +01:00
|
|
|
lock (_lock)
|
|
|
|
|
{
|
|
|
|
|
(_stack.Value ??= new ConcurrentStack<IScope>()).Push(scope);
|
|
|
|
|
}
|
2022-06-20 09:20:47 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|