Files
tiku-backend.net/Tiku.Infrastructure/Tenancy/TenantExecutionScope.cs

51 lines
1.7 KiB
C#

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Tiku.Application.Security;
namespace Tiku.Infrastructure.Tenancy;
public sealed class TenantExecutionScope(
IServiceScopeFactory scopeFactory,
ILogger<TenantExecutionScope> logger) : ITenantExecutionScope
{
public Task ExecuteAsync(
Guid? targetTenantId,
string reason,
Func<IServiceProvider, CancellationToken, Task> operation,
CancellationToken cancellationToken = default)
{
return ExecuteAsync<object?>(
targetTenantId,
reason,
async (provider, token) =>
{
await operation(provider, token);
return null;
},
cancellationToken);
}
public async Task<TResult> ExecuteAsync<TResult>(
Guid? targetTenantId,
string reason,
Func<IServiceProvider, CancellationToken, Task<TResult>> operation,
CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(operation);
if (string.IsNullOrWhiteSpace(reason))
{
throw new ArgumentException("A system scope requires an audit reason.", nameof(reason));
}
await using var scope = scopeFactory.CreateAsyncScope();
var initializer = scope.ServiceProvider.GetRequiredService<ITenantContextInitializer>();
initializer.InitializeSystem(targetTenantId, reason);
logger.LogWarning(
"Entering audited system tenant scope. TargetTenantId={TargetTenantId} Reason={Reason}",
targetTenantId,
reason);
return await operation(scope.ServiceProvider, cancellationToken);
}
}