using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using System; using System.Linq; using APT.Infrastructure.Api; namespace APT.Infrastructure.EF { public class TenantConnectionResolver : ITenantConnectionResolver where TDbContext : DbContext { private readonly TenantSettings setting; private readonly TenantInfo tenantInfo; private readonly IServiceProvider serviceProvider; private readonly TenantOption tenantOption; public TenantConnectionResolver(TenantSettings setting, TenantInfo tenantInfo, TenantOption tenantOption, IServiceProvider serviceProvider) { this.tenantOption = tenantOption; this.setting = setting; this.tenantInfo = tenantInfo; this.serviceProvider = serviceProvider; } public string GetConnection() { var connectionGenerator = this.GetConnectionGenerator(); var option = GenerateOption(); return connectionGenerator.GetConnection(option, tenantInfo); } IConnectionGenerator GetConnectionGenerator() { IConnectionGenerator connectionGenerator = this.setting.ConnectionGenerator?.Invoke() ?? serviceProvider.GetServices() .FirstOrDefault(r => r.TenantKey == this.setting.Key || r.MatchTenantKey(this.setting.Key)) ?? serviceProvider.GetService(); return connectionGenerator; } TenantOption GenerateOption() { tenantOption.Key = setting.Key; tenantOption.ConnectionType = setting.ConnectionType; tenantOption.DbType = setting.DbType; tenantOption.TableNameFunc = setting.TableNameFunc; tenantOption.SchemaFunc = setting.SchemaFunc; tenantOption.ConnectionPrefix = setting.ConnectionPrefix; tenantOption.ConnectionName = setting.ConnectionName; return this.tenantOption; } } }