forked from xiongyuxing/tiku-backend.net
51 lines
1.7 KiB
C#
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);
|
|
}
|
|
}
|