using System.Collections.Concurrent; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Volo.Abp.DependencyInjection; using Volo.Abp.Uow; using Yi.Framework.TenantManagement.Application.Contracts; namespace FoodLabeling.Th.Application.MultiTenancy; /// /// 使用独立 DI Scope 在后台执行 ,避免阻塞 HTTP 请求。 /// public class ThTenantDatabaseBackgroundInitializer : IThTenantDatabaseBackgroundInitializer, ISingletonDependency { private readonly IServiceScopeFactory _scopeFactory; private readonly ILogger _logger; private static readonly ConcurrentDictionary Running = new(); public ThTenantDatabaseBackgroundInitializer( IServiceScopeFactory scopeFactory, ILogger logger) { _scopeFactory = scopeFactory; _logger = logger; } /// public void Enqueue(Guid tenantId) { if (!Running.TryAdd(tenantId, 0)) { _logger.LogInformation("租户 {TenantId} 业务库初始化已在进行中,跳过重复入队", tenantId); return; } _ = Task.Run(() => RunInitAsync(tenantId)); } private async Task RunInitAsync(Guid tenantId) { try { _logger.LogInformation("租户 {TenantId} 业务库后台初始化开始", tenantId); using var scope = _scopeFactory.CreateScope(); var uowManager = scope.ServiceProvider.GetRequiredService(); var tenantService = scope.ServiceProvider.GetRequiredService(); using var uow = uowManager.Begin(requiresNew: true, isTransactional: false); await tenantService.InitAsync(tenantId); await uow.CompleteAsync(); _logger.LogInformation("租户 {TenantId} 业务库后台初始化完成", tenantId); } catch (Exception ex) { _logger.LogError(ex, "租户 {TenantId} 业务库后台初始化失败", tenantId); } finally { Running.TryRemove(tenantId, out _); } } }