diff --git a/src/Volo.Abp.MultiTenancy/Volo/Abp/Data/MultiTenancy/ITenantConnectionStringStore.cs b/src/Volo.Abp.MultiTenancy/Volo/Abp/Data/MultiTenancy/ITenantConnectionStringStore.cs index 41701d0720..fde063d053 100644 --- a/src/Volo.Abp.MultiTenancy/Volo/Abp/Data/MultiTenancy/ITenantConnectionStringStore.cs +++ b/src/Volo.Abp.MultiTenancy/Volo/Abp/Data/MultiTenancy/ITenantConnectionStringStore.cs @@ -5,6 +5,9 @@ namespace Volo.Abp.Data.MultiTenancy public interface ITenantConnectionStringStore { [CanBeNull] - string GetConnectionStringOrNull([NotNull] string tenantId, [CanBeNull] string connStringName); + string GetDefaultConnectionStringOrNull([NotNull] string tenantId); + + [CanBeNull] + string GetConnectionStringOrNull([NotNull] string tenantId, [NotNull] string connStringName); } } \ No newline at end of file diff --git a/src/Volo.Abp.MultiTenancy/Volo/Abp/Data/MultiTenancy/MultiTenantConnectionStringResolver.cs b/src/Volo.Abp.MultiTenancy/Volo/Abp/Data/MultiTenancy/MultiTenantConnectionStringResolver.cs index ed9d41e9a8..be4d3717b0 100644 --- a/src/Volo.Abp.MultiTenancy/Volo/Abp/Data/MultiTenancy/MultiTenantConnectionStringResolver.cs +++ b/src/Volo.Abp.MultiTenancy/Volo/Abp/Data/MultiTenancy/MultiTenantConnectionStringResolver.cs @@ -1,10 +1,10 @@ using Microsoft.Extensions.Options; using Volo.Abp.MultiTenancy; using Volo.DependencyInjection; +using Volo.ExtensionMethods.Collections.Generic; namespace Volo.Abp.Data.MultiTenancy { - //TODO: It would be better to use composition over inheritance on connection string resolve progress! //TODO: Create a replace service registration convention, instead of custom registration in AbpMultiTenancyModule? [DisableConventionalRegistration] @@ -26,20 +26,40 @@ namespace Volo.Abp.Data.MultiTenancy public override string Resolve(string connectionStringName = null) { var tenant = _multiTenancyManager.CurrentTenant; + + //No current tenant, fallback to default logic if (tenant == null) { return base.Resolve(connectionStringName); } - var connectionString = _tenantConnectionStringStore.GetConnectionStringOrNull(tenant.Id, connectionStringName); - if (connectionString == null) + //Requesting default connection string + if (connectionStringName == null) { - return base.Resolve(connectionStringName); + return _tenantConnectionStringStore.GetDefaultConnectionStringOrNull(tenant.Id) ?? + Options.ConnectionStrings.Default; } - //TODO: If given tenant did not specified a connectionStringName specific connection string, then use the default connection string for connectionStringName, not tenant's default database + //Requesting specific connection string + var connString = _tenantConnectionStringStore.GetConnectionStringOrNull(tenant.Id, connectionStringName); + if (connString != null) + { + return connString; + } + + /* Requested a specific connection string, but it's not specified for the tenant. + * - If it's specified in options, use it. + * - If not, use tenant's default conn string. + */ + + var connStringInOptions = Options.ConnectionStrings.GetOrDefault(connectionStringName); + if (connStringInOptions != null) + { + return connStringInOptions; + } - return connectionString; + return _tenantConnectionStringStore.GetDefaultConnectionStringOrNull(tenant.Id) ?? + Options.ConnectionStrings.Default; } } } diff --git a/src/Volo.Abp.MultiTenancy/Volo/Abp/Data/MultiTenancy/NullTenantConnectionStringStore.cs b/src/Volo.Abp.MultiTenancy/Volo/Abp/Data/MultiTenancy/NullTenantConnectionStringStore.cs index b7cf52fb62..5762b305e4 100644 --- a/src/Volo.Abp.MultiTenancy/Volo/Abp/Data/MultiTenancy/NullTenantConnectionStringStore.cs +++ b/src/Volo.Abp.MultiTenancy/Volo/Abp/Data/MultiTenancy/NullTenantConnectionStringStore.cs @@ -4,6 +4,12 @@ namespace Volo.Abp.Data.MultiTenancy { public sealed class NullTenantConnectionStringStore : ITenantConnectionStringStore, ISingletonDependency { + public string GetDefaultConnectionStringOrNull(string tenantId) + { + //No tenant specific connection string by default + return null; + } + public string GetConnectionStringOrNull(string tenantId, string connStringName) { //No tenant specific connection string by default diff --git a/src/Volo.Abp/Volo/Abp/Data/DefaultConnectionStringResolver.cs b/src/Volo.Abp/Volo/Abp/Data/DefaultConnectionStringResolver.cs index d9283749d5..79f152000d 100644 --- a/src/Volo.Abp/Volo/Abp/Data/DefaultConnectionStringResolver.cs +++ b/src/Volo.Abp/Volo/Abp/Data/DefaultConnectionStringResolver.cs @@ -7,11 +7,11 @@ namespace Volo.Abp.Data { public class DefaultConnectionStringResolver : IConnectionStringResolver, ITransientDependency { - private readonly DbConnectionOptions _options; + protected DbConnectionOptions Options { get; } public DefaultConnectionStringResolver(IOptionsSnapshot options) { - _options = options.Value; + Options = options.Value; } public virtual string Resolve(string connectionStringName = null) @@ -19,7 +19,7 @@ namespace Volo.Abp.Data //Get module specific value if provided if (!connectionStringName.IsNullOrEmpty()) { - var moduleConnString = _options.ConnectionStrings.GetOrDefault(connectionStringName); + var moduleConnString = Options.ConnectionStrings.GetOrDefault(connectionStringName); if (!moduleConnString.IsNullOrEmpty()) { return moduleConnString; @@ -27,7 +27,7 @@ namespace Volo.Abp.Data } //Get default value - return _options.ConnectionStrings.Default; + return Options.ConnectionStrings.Default; } } } \ No newline at end of file diff --git a/src/Volo.Abp/Volo/Abp/Data/IConnectionStringResolver.cs b/src/Volo.Abp/Volo/Abp/Data/IConnectionStringResolver.cs index 2433648aae..e9344ef66a 100644 --- a/src/Volo.Abp/Volo/Abp/Data/IConnectionStringResolver.cs +++ b/src/Volo.Abp/Volo/Abp/Data/IConnectionStringResolver.cs @@ -1,7 +1,10 @@ -namespace Volo.Abp.Data +using JetBrains.Annotations; + +namespace Volo.Abp.Data { public interface IConnectionStringResolver { + [NotNull] string Resolve(string connectionStringName = null); } } diff --git a/test/Volo.Abp.MultiTenancy.Tests/Volo/Abp/Data/MultiTenancy/MultiTenantConnectionStringResolver_Tests.cs b/test/Volo.Abp.MultiTenancy.Tests/Volo/Abp/Data/MultiTenancy/MultiTenantConnectionStringResolver_Tests.cs index f9da6f83b3..d624419a13 100644 --- a/test/Volo.Abp.MultiTenancy.Tests/Volo/Abp/Data/MultiTenancy/MultiTenantConnectionStringResolver_Tests.cs +++ b/test/Volo.Abp.MultiTenancy.Tests/Volo/Abp/Data/MultiTenancy/MultiTenantConnectionStringResolver_Tests.cs @@ -3,6 +3,7 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Options; using Shouldly; using Volo.Abp.MultiTenancy; +using Volo.ExtensionMethods.Collections.Generic; using Xunit; namespace Volo.Abp.Data.MultiTenancy @@ -73,22 +74,12 @@ namespace Volo.Abp.Data.MultiTenancy public string GetConnectionStringOrNull(string tenantId, string connStringName) { - if (connStringName != null) - { - if (_options.Value.ConnectionStrings.ContainsKey(tenantId + "#" + connStringName)) - { - return _options.Value.ConnectionStrings[tenantId + "#" + connStringName]; - } - } - else - { - if (_options.Value.ConnectionStrings.ContainsKey(tenantId + "#Default")) - { - return _options.Value.ConnectionStrings[tenantId + "#Default"]; - } - } + return _options.Value.ConnectionStrings.GetOrDefault(tenantId + "#" + connStringName); + } - return null; + public string GetDefaultConnectionStringOrNull(string tenantId) + { + return _options.Value.ConnectionStrings.GetOrDefault(tenantId + "#Default"); } } }