using Abp.Configuration.Startup;
using Abp.Domain.Uow;
using Abp.Extensions;
using Abp.MultiTenancy;
using Abp.Runtime.Session;
using IwbZero.MultiTenancy;
namespace IwbZero.EntityFramework
{
///
/// Implements to dynamically resolve
/// connection string for a multi tenant application.
///
public class DbPerTenantConnectionStringResolver : DefaultConnectionStringResolver, IDbPerTenantConnectionStringResolver
{
///
/// Reference to the session.
///
public IAbpSession AbpSession { get; set; }
private readonly ICurrentUnitOfWorkProvider _currentUnitOfWorkProvider;
private readonly ITenantCache _tenantCache;
///
/// Initializes a new instance of the class.
///
public DbPerTenantConnectionStringResolver(
IAbpStartupConfiguration configuration,
ICurrentUnitOfWorkProvider currentUnitOfWorkProvider,
ITenantCache tenantCache)
: base(
configuration)
{
_currentUnitOfWorkProvider = currentUnitOfWorkProvider;
_tenantCache = tenantCache;
AbpSession = NullAbpSession.Instance;
}
public override string GetNameOrConnectionString(ConnectionStringResolveArgs args)
{
if (args.MultiTenancySide == MultiTenancySides.Host)
{
return GetNameOrConnectionString(new DbPerTenantConnectionStringResolveArgs(null, args));
}
return GetNameOrConnectionString(new DbPerTenantConnectionStringResolveArgs(GetCurrentTenantId(), args));
}
public virtual string GetNameOrConnectionString(DbPerTenantConnectionStringResolveArgs args)
{
if (args.TenantId == null)
{
//Requested for host
return base.GetNameOrConnectionString(args);
}
var tenantCacheItem = _tenantCache.Get(args.TenantId.Value);
if (tenantCacheItem==null||tenantCacheItem.ConnectionString.IsNullOrEmpty())
{
//Tenant has not dedicated database
return base.GetNameOrConnectionString(args);
}
return tenantCacheItem.ConnectionString;
}
protected virtual int? GetCurrentTenantId()
{
return _currentUnitOfWorkProvider.Current != null
? _currentUnitOfWorkProvider.Current.GetTenantId()
: AbpSession.TenantId;
}
}
}