@ -1,6 +1,8 @@
using System ;
using System.Linq ;
using JetBrains.Annotations ;
using Microsoft.Extensions.DependencyInjection ;
using Microsoft.Extensions.Logging ;
using Microsoft.Extensions.Options ;
using Volo.DependencyInjection ;
@ -8,23 +10,66 @@ namespace Volo.Abp.MultiTenancy
{
public class MultiTenancyManager : IMultiTenancyManager , ITransientDependency
{
public TenantInfo CurrentTenant = > GetCurrentTenant ( ) ;
public TenantInformation CurrentTenant = > GetCurrentTenant ( ) ;
private readonly IServiceProvider _ serviceProvider ;
private readonly ITenantScopeProvider _ tenantScopeProvider ;
private readonly ITenantStore _ tenantStore ;
private readonly MultiTenancyOptions _ options ;
private readonly ILogger < MultiTenancyManager > _l ogger ;
public MultiTenancyManager (
IServiceProvider serviceProvider ,
ITenantScopeProvider tenantScopeProvider ,
IOptions < MultiTenancyOptions > options )
IOptions < MultiTenancyOptions > options ,
ITenantStore tenantStore ,
ILogger < MultiTenancyManager > logger )
{
_ serviceProvider = serviceProvider ;
_ tenantScopeProvider = tenantScopeProvider ;
_ tenantStore = tenantStore ;
_l ogger = logger ;
_ options = options . Value ;
}
protected virtual TenantInfo GetCurrentTenant ( )
public IDisposable ChangeTenant ( Guid ? tenantId )
{
if ( tenantId = = null )
{
return ChangeToHost ( ) ;
}
var tenant = _ tenantStore . Find ( tenantId . Value ) ;
if ( tenant = = null )
{
throw new AbpException ( "There is no tenant with given tenant id: " + tenantId . Value ) ;
}
return _ tenantScopeProvider . EnterScope ( tenant ) ;
}
public IDisposable ChangeTenant ( string name )
{
if ( name = = null )
{
return ChangeToHost ( ) ;
}
var tenant = _ tenantStore . Find ( name ) ;
if ( tenant = = null )
{
throw new AbpException ( "There is no tenant with given tenant name: " + name ) ;
}
return _ tenantScopeProvider . EnterScope ( tenant ) ;
}
public IDisposable ChangeToHost ( )
{
return _ tenantScopeProvider . EnterScope ( null ) ;
}
protected virtual TenantInformation GetCurrentTenant ( )
{
if ( _ tenantScopeProvider . CurrentScope ! = null )
{
@ -34,8 +79,10 @@ namespace Volo.Abp.MultiTenancy
return GetCurrentTenantFromResolvers ( ) ;
}
protected virtual TenantInfo GetCurrentTenantFromResolvers ( )
protected virtual TenantInformation GetCurrentTenantFromResolvers ( )
{
//TODO: Can be optimized by some caching mechanism?
if ( ! _ options . TenantResolvers . Any ( ) )
{
return null ;
@ -49,23 +96,42 @@ namespace Volo.Abp.MultiTenancy
{
tenantResolver . Resolve ( context ) ;
//TODO: Validate TenantId by a TenantStore (TenantId can be TenancyName, so also normalize it by tenant store)
if ( context . IsHandled ( ) )
if ( context . ResolvedTenantOrHost ( ) )
{
break ;
if ( context . TenantIdOrName = = null )
{
//Resolved host!
return null ;
}
var tenant = GetValidatedTenantOrNull ( context . TenantIdOrName ) ;
if ( tenant ! = null )
{
return tenant ;
}
_l ogger . LogWarning ( $"Resolved tenancy name '{context.TenantIdOrName}' by '{tenantResolver.GetType().FullName}' but could not find in current tenant store." ) ;
context . TenantIdOrName = null ;
}
context . Handled = null ;
context . Handled = false ;
}
return context . Tenant ;
//Could not find a tenant
return null ;
}
}
public IDisposable ChangeTenant ( TenantInfo tenant )
[CanBeNull]
private TenantInformation GetValidatedTenantOrNull ( [ NotNull ] string tenantIdOrName )
{
return _ tenantScopeProvider . EnterScope ( tenant ) ;
Guid tenantId ;
if ( Guid . TryParse ( tenantIdOrName , out tenantId ) )
{
return _ tenantStore . Find ( tenantId ) ;
}
return _ tenantStore . Find ( tenantIdOrName ) ;
}
}
}