Browse Source

Merged IMultiTenancyManager with ICurrentTenant

pull/191/head
Halil İbrahim Kalkan 9 years ago
parent
commit
6f6fcfb798
  1. 1
      src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs
  2. 36
      src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/CurrentTenant.cs
  3. 17
      src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/ICurrentTenant.cs
  4. 15
      src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/IMultiTenancyManager.cs
  5. 16
      src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/ITenantScopeProvider.cs
  6. 18
      src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/MultiTenancyManagerCurrentTenant.cs
  7. 16
      src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/MultiTenantConnectionStringResolver.cs
  8. 12
      src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/NullCurrentTenant.cs
  9. 8
      src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/TenantScopeProvider.cs
  10. 4
      test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/App/AppModule.cs
  11. 8
      test/Volo.Abp.MultiTenancy.Tests/Volo/Abp/Data/MultiTenancy/MultiTenantConnectionStringResolver_Tests.cs
  12. 44
      test/Volo.Abp.MultiTenancy.Tests/Volo/Abp/MultiTenancy/CurrentTenant_Tests.cs

1
src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs

@ -37,7 +37,6 @@ namespace Volo.Abp.EntityFrameworkCore
: base(options)
{
GuidGenerator = SimpleGuidGenerator.Instance;
CurrentTenant = NullCurrentTenant.Instance;
}
protected override void OnModelCreating(ModelBuilder modelBuilder)

36
src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/MultiTenancyManager.cs → src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/CurrentTenant.cs

@ -1,24 +1,30 @@
using System;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.MultiTenancy
{
//TODO: This is very similar to ITenantScopeProvider. Consider to unify them!
public class MultiTenancyManager : IMultiTenancyManager, ITransientDependency
public class CurrentTenant : ICurrentTenant, ITransientDependency
{
public TenantInfo CurrentTenant => GetCurrentTenant();
public bool IsAvailable => Id.HasValue;
public Guid? Id => GetCurrentTenant()?.Id;
public string Name => GetCurrentTenant()?.Name;
public ConnectionStrings ConnectionStrings => GetCurrentTenant()?.ConnectionStrings;
private readonly ITenantScopeProvider _tenantScopeProvider;
private readonly TenantScopeProvider _tenantScopeProvider;
private readonly ITenantStore _tenantStore;
private readonly ILogger<MultiTenancyManager> _logger;
private readonly ILogger<CurrentTenant> _logger;
private readonly ITenantResolver _tenantResolver;
public MultiTenancyManager(
ITenantScopeProvider tenantScopeProvider,
public CurrentTenant(
TenantScopeProvider tenantScopeProvider,
ITenantStore tenantStore,
ILogger<MultiTenancyManager> logger,
ILogger<CurrentTenant> logger,
ITenantResolver tenantResolver)
{
_tenantScopeProvider = tenantScopeProvider;
@ -27,23 +33,23 @@ namespace Volo.Abp.MultiTenancy
_tenantResolver = tenantResolver;
}
public IDisposable ChangeTenant(Guid? tenantId)
public IDisposable Change(Guid? id)
{
if (tenantId == null)
if (id == null)
{
return _tenantScopeProvider.EnterScope(null);
}
var tenant = _tenantStore.Find(tenantId.Value);
var tenant = _tenantStore.Find(id.Value);
if (tenant == null)
{
throw new AbpException("There is no tenant with given tenant id: " + tenantId.Value);
throw new AbpException("There is no tenant with given tenant id: " + id.Value);
}
return _tenantScopeProvider.EnterScope(tenant);
}
public IDisposable ChangeTenant(string name)
public IDisposable Change(string name)
{
if (name == null)
{
@ -59,6 +65,7 @@ namespace Volo.Abp.MultiTenancy
return _tenantScopeProvider.EnterScope(tenant);
}
[CanBeNull]
protected virtual TenantInfo GetCurrentTenant()
{
if (_tenantScopeProvider.CurrentScope != null)
@ -71,6 +78,7 @@ namespace Volo.Abp.MultiTenancy
return ResolveTenant();
}
[CanBeNull]
protected virtual TenantInfo ResolveTenant()
{
var tenantIdOrName = _tenantResolver.ResolveTenantIdOrName();

17
src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/ICurrentTenant.cs

@ -1,9 +1,26 @@
using System;
using JetBrains.Annotations;
using Volo.Abp.Data;
namespace Volo.Abp.MultiTenancy
{
public interface ICurrentTenant
{
bool IsAvailable { get; }
[CanBeNull]
Guid? Id { get; }
[CanBeNull]
string Name { get; }
[CanBeNull]
ConnectionStrings ConnectionStrings { get; }
[NotNull]
IDisposable Change(Guid? id);
[NotNull]
IDisposable Change([CanBeNull] string name);
}
}

15
src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/IMultiTenancyManager.cs

@ -1,15 +0,0 @@
using System;
using JetBrains.Annotations;
namespace Volo.Abp.MultiTenancy
{
public interface IMultiTenancyManager
{
[CanBeNull]
TenantInfo CurrentTenant { get; }
IDisposable ChangeTenant(Guid? tenantId);
IDisposable ChangeTenant([CanBeNull] string name);
}
}

16
src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/ITenantScopeProvider.cs

@ -1,16 +0,0 @@
using System;
using JetBrains.Annotations;
namespace Volo.Abp.MultiTenancy
{
public interface ITenantScopeProvider
{
/// <summary>
/// Can be null for host.
/// </summary>
[CanBeNull]
TenantScope CurrentScope { get; }
IDisposable EnterScope([CanBeNull] TenantInfo tenant);
}
}

18
src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/MultiTenancyManagerCurrentTenant.cs

@ -1,18 +0,0 @@
using System;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.MultiTenancy
{
[Dependency(ReplaceServices = true)]
public class MultiTenancyManagerCurrentTenant : ICurrentTenant, ITransientDependency
{
public Guid? Id => _multiTenancyManager.CurrentTenant?.Id;
private readonly IMultiTenancyManager _multiTenancyManager;
public MultiTenancyManagerCurrentTenant(IMultiTenancyManager multiTenancyManager)
{
_multiTenancyManager = multiTenancyManager;
}
}
}

16
src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/MultiTenantConnectionStringResolver.cs

@ -8,22 +8,22 @@ namespace Volo.Abp.MultiTenancy
[Dependency(ReplaceServices = true)]
public class MultiTenantConnectionStringResolver : DefaultConnectionStringResolver
{
private readonly IMultiTenancyManager _multiTenancyManager;
private readonly ICurrentTenant _currentTenant;
public MultiTenantConnectionStringResolver(
IOptionsSnapshot<DbConnectionOptions> options,
IMultiTenancyManager multiTenancyManager)
ICurrentTenant currentTenant)
: base(options)
{
_multiTenancyManager = multiTenancyManager;
_currentTenant = currentTenant;
}
public override string Resolve(string connectionStringName = null)
{
var tenant = _multiTenancyManager.CurrentTenant;
var tenantConnectionStrings = _currentTenant.ConnectionStrings;
//No current tenant, fallback to default logic
if (tenant == null)
if (tenantConnectionStrings == null)
{
return base.Resolve(connectionStringName);
}
@ -31,12 +31,12 @@ namespace Volo.Abp.MultiTenancy
//Requesting default connection string
if (connectionStringName == null)
{
return tenant.ConnectionStrings.Default ??
return tenantConnectionStrings.Default ??
Options.ConnectionStrings.Default;
}
//Requesting specific connection string
var connString = tenant.ConnectionStrings.GetOrDefault(connectionStringName);
var connString = tenantConnectionStrings.GetOrDefault(connectionStringName);
if (connString != null)
{
return connString;
@ -53,7 +53,7 @@ namespace Volo.Abp.MultiTenancy
return connStringInOptions;
}
return tenant.ConnectionStrings.Default ??
return tenantConnectionStrings.Default ??
Options.ConnectionStrings.Default;
}
}

12
src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/NullCurrentTenant.cs

@ -1,12 +0,0 @@
using System;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.MultiTenancy
{
public class NullCurrentTenant : ICurrentTenant, ISingletonDependency
{
public static NullCurrentTenant Instance { get; } = new NullCurrentTenant();
public Guid? Id { get; } = null;
}
}

8
src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/AsyncLocalTenantScopeProvider.cs → src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/TenantScopeProvider.cs

@ -4,17 +4,17 @@ using Volo.Abp.DependencyInjection;
namespace Volo.Abp.MultiTenancy
{
public class AsyncLocalTenantScopeProvider : ITenantScopeProvider, ISingletonDependency
public class TenantScopeProvider : ISingletonDependency
{
public TenantScope CurrentScope
{
get { return _currentScope.Value; }
private set { _currentScope.Value = value; }
get => _currentScope.Value;
private set => _currentScope.Value = value;
}
private readonly AsyncLocal<TenantScope> _currentScope;
public AsyncLocalTenantScopeProvider()
public TenantScopeProvider()
{
_currentScope = new AsyncLocal<TenantScope>();
}

4
test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/App/AppModule.cs

@ -32,12 +32,12 @@ namespace Volo.Abp.AspNetCore.App
app.Run(async (ctx) =>
{
var manager = ctx.RequestServices.GetRequiredService<IMultiTenancyManager>();
var currentTenant = ctx.RequestServices.GetRequiredService<ICurrentTenant>();
var jsonSerializer = ctx.RequestServices.GetRequiredService<IJsonSerializer>();
var dictionary = new Dictionary<string, string>
{
["TenantId"] = manager.CurrentTenant == null ? "" : manager.CurrentTenant.Id.ToString()
["TenantId"] = currentTenant.IsAvailable ? currentTenant.Id.ToString() : ""
};
var result = jsonSerializer.Serialize(dictionary, camelCase: false);

8
test/Volo.Abp.MultiTenancy.Tests/Volo/Abp/Data/MultiTenancy/MultiTenantConnectionStringResolver_Tests.cs

@ -9,12 +9,12 @@ namespace Volo.Abp.Data.MultiTenancy
{
public class MultiTenantConnectionStringResolver_Tests : MultiTenancyTestBase
{
private readonly IMultiTenancyManager _multiTenancyManager;
private readonly ICurrentTenant _currentTenant;
private readonly IConnectionStringResolver _connectionResolver;
public MultiTenantConnectionStringResolver_Tests()
{
_multiTenancyManager = ServiceProvider.GetRequiredService<IMultiTenancyManager>();
_currentTenant = ServiceProvider.GetRequiredService<ICurrentTenant>();
_connectionResolver = ServiceProvider.GetRequiredService<IConnectionStringResolver>();
_connectionResolver.ShouldBeOfType<MultiTenantConnectionStringResolver>();
@ -53,7 +53,7 @@ namespace Volo.Abp.Data.MultiTenancy
_connectionResolver.Resolve("db1").ShouldBe("db1-default-value");
//Overrided connection strings for tenant1
using (_multiTenancyManager.ChangeTenant("tenant1"))
using (_currentTenant.Change("tenant1"))
{
_connectionResolver.Resolve().ShouldBe("tenant1-default-value");
_connectionResolver.Resolve("db1").ShouldBe("tenant1-db1-value");
@ -64,7 +64,7 @@ namespace Volo.Abp.Data.MultiTenancy
_connectionResolver.Resolve("db1").ShouldBe("db1-default-value");
//Undefined connection strings for tenant2
using (_multiTenancyManager.ChangeTenant("tenant2"))
using (_currentTenant.Change("tenant2"))
{
_connectionResolver.Resolve().ShouldBe("default-value");
_connectionResolver.Resolve("db1").ShouldBe("db1-default-value");

44
test/Volo.Abp.MultiTenancy.Tests/Volo/Abp/MultiTenancy/MultiTenantManager_Tests.cs → test/Volo.Abp.MultiTenancy.Tests/Volo/Abp/MultiTenancy/CurrentTenant_Tests.cs

@ -6,17 +6,17 @@ using Xunit;
namespace Volo.Abp.MultiTenancy
{
public class MultiTenantManager_Tests : MultiTenancyTestBase
public class CurrentTenant_Tests : MultiTenancyTestBase
{
private readonly IMultiTenancyManager _multiTenancyManager;
private readonly ICurrentTenant _currentTenant;
private readonly string _tenantA = "A";
private readonly string _tenantB = "B";
private string _tenantToBeResolved;
public MultiTenantManager_Tests()
public CurrentTenant_Tests()
{
_multiTenancyManager = ServiceProvider.GetRequiredService<IMultiTenancyManager>();
_currentTenant = ServiceProvider.GetRequiredService<ICurrentTenant>();
}
[Fact]
@ -24,7 +24,7 @@ namespace Volo.Abp.MultiTenancy
{
//Assert
_multiTenancyManager.CurrentTenant.ShouldBeNull();
_currentTenant.Id.ShouldBeNull();
}
protected override void BeforeAddApplication(IServiceCollection services)
@ -70,8 +70,8 @@ namespace Volo.Abp.MultiTenancy
//Assert
Assert.NotNull(_multiTenancyManager.CurrentTenant);
_multiTenancyManager.CurrentTenant.Name.ShouldBe(_tenantA);
Assert.NotNull(_currentTenant.Id);
_currentTenant.Name.ShouldBe(_tenantA);
}
[Fact]
@ -83,37 +83,37 @@ namespace Volo.Abp.MultiTenancy
//Assert
Assert.NotNull(_multiTenancyManager.CurrentTenant);
_multiTenancyManager.CurrentTenant.Name.ShouldBe(_tenantB);
Assert.NotNull(_currentTenant.Id);
_currentTenant.Name.ShouldBe(_tenantB);
}
[Fact]
public void Should_Get_Changed_Tenant_If_Wanted()
{
_multiTenancyManager.CurrentTenant.ShouldBe(null);
_currentTenant.Id.ShouldBe(null);
_tenantToBeResolved = _tenantB;
Assert.NotNull(_multiTenancyManager.CurrentTenant);
_multiTenancyManager.CurrentTenant.Name.ShouldBe(_tenantB);
Assert.NotNull(_currentTenant.Id);
_currentTenant.Name.ShouldBe(_tenantB);
using (_multiTenancyManager.ChangeTenant(_tenantA))
using (_currentTenant.Change(_tenantA))
{
Assert.NotNull(_multiTenancyManager.CurrentTenant);
_multiTenancyManager.CurrentTenant.Name.ShouldBe(_tenantA);
Assert.NotNull(_currentTenant.Id);
_currentTenant.Name.ShouldBe(_tenantA);
using (_multiTenancyManager.ChangeTenant(_tenantB))
using (_currentTenant.Change(_tenantB))
{
Assert.NotNull(_multiTenancyManager.CurrentTenant);
_multiTenancyManager.CurrentTenant.Name.ShouldBe(_tenantB);
Assert.NotNull(_currentTenant.Id);
_currentTenant.Name.ShouldBe(_tenantB);
}
Assert.NotNull(_multiTenancyManager.CurrentTenant);
_multiTenancyManager.CurrentTenant.Name.ShouldBe(_tenantA);
Assert.NotNull(_currentTenant.Id);
_currentTenant.Name.ShouldBe(_tenantA);
}
Assert.NotNull(_multiTenancyManager.CurrentTenant);
_multiTenancyManager.CurrentTenant.Name.ShouldBe(_tenantB);
Assert.NotNull(_currentTenant.Id);
_currentTenant.Name.ShouldBe(_tenantB);
}
}
}
Loading…
Cancel
Save