我需要在设计时将
ICurrentTenantRepository
接口的实例传递到我的 AppDbContext
类的构造函数中,但我不知道该怎么做。我对这个主题做了很多研究,但没有找到任何对我有帮助的东西......
如果我在设计时不创建它,它可以正常工作,但如果我在设计时创建它,我需要创建一个新的
AppDbContext
实例,此时我不知道该怎么做。
有人知道如何帮助我吗?
谢谢!
public sealed class AppDbContext : DbContext, IUnitOfWork
{
private readonly ICurrentTenantRepository _currentTenantRepository;
public string CurrentTenantId { get; set; }
public string CurrentTenantConnectionString { get; set; }
public AppDbContext(DbContextOptions<AppDbContext> options, ICurrentTenantRepository currentTenantRepository) : base(options)
{
_currentTenantRepository = currentTenantRepository;
if (_currentTenantRepository is not null)
{
CurrentTenantId = _currentTenantRepository.TenantId;
CurrentTenantConnectionString = _currentTenantRepository.ConnectionString;
}
ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
ChangeTracker.AutoDetectChangesEnabled = false;
}
}
public class AppDbContextFactory : IDesignTimeDbContextFactory<AppDbContext>
{
public AppDbContext CreateDbContext(string[] args) // neccessary for EF migration designer to run on this context
{
var builder = WebApplication.CreateBuilder(args);
var optionsBuilder = new DbContextOptionsBuilder<AppDbContext>();
optionsBuilder.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"));
return new AppDbContext(optionsBuilder.Options);
}
}
public interface ICurrentTenantRepository
{
string? ConnectionString { get; set; }
string? TenantId { get; set; }
public Task<bool> SetTenant(string tenant);
}
public class CurrentTenantRepository : ICurrentTenantRepository
{
private readonly TenantDbContext _context;
public string? ConnectionString { get; set; }
public string? TenantId { get; set; }
public CurrentTenantRepository(TenantDbContext context)
{
_context = context;
}
public async Task<bool> SetTenant(string tenant)
{
var tenantInfo = await _context.Tenants.Where(x => x.Id == tenant).FirstOrDefaultAsync(); // check if tenant exists
if (tenantInfo != null)
{
TenantId = tenant;
ConnectionString = tenantInfo.ConnectionString; // optional connection string per tenant (can be null to use default database)
return true;
}
else
{
throw new Exception("Tenant invalid");
}
}
}
谢谢@Tanveer Badar
解决方案:
返回 new AppDbContext(optionsBuilder.Options, new CurrentTenantRepository(new TenantDbContext(new DbContextOptions())));