Browse Source

Merge pull request #7619 from abpframework/module-db-group

Define and handle AbpDbConnectionOptions.Databases option.
pull/7654/head
Halil İbrahim Kalkan 5 years ago
committed by GitHub
parent
commit
4bf04bbb18
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDataModule.cs
  2. 28
      framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDatabaseInfo.cs
  3. 58
      framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDatabaseInfoDictionary.cs
  4. 44
      framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDbConnectionOptions.cs
  5. 25
      framework/src/Volo.Abp.Data/Volo/Abp/Data/DefaultConnectionStringResolver.cs
  6. 30
      framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/MultiTenantConnectionStringResolver.cs

9
framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDataModule.cs

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.Modularity;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Uow;
@ -27,6 +28,14 @@ namespace Volo.Abp.Data
context.Services.AddSingleton(typeof(IDataFilter<>), typeof(DataFilter<>));
}
public override void PostConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpDbConnectionOptions>(options =>
{
options.Databases.RefreshIndexes();
});
}
private static void AutoAddDataSeedContributors(IServiceCollection services)
{
var contributors = new List<Type>();

28
framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDatabaseInfo.cs

@ -0,0 +1,28 @@
using System.Collections.Generic;
namespace Volo.Abp.Data
{
public class AbpDatabaseInfo
{
public string DatabaseName { get; set; }
/// <summary>
/// List of connection names mapped to this database.
/// </summary>
public HashSet<string> MappedConnections { get; }
/// <summary>
/// Is this database used by tenants. Set this to true if this database
/// can't owned by tenants.
///
/// Default: true.
/// </summary>
public bool IsUsedByTenants { get; set; } = true;
internal AbpDatabaseInfo(string databaseName)
{
DatabaseName = databaseName;
MappedConnections = new HashSet<string>();
}
}
}

58
framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDatabaseInfoDictionary.cs

@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
namespace Volo.Abp.Data
{
public class AbpDatabaseInfoDictionary : Dictionary<string, AbpDatabaseInfo>
{
private Dictionary<string, AbpDatabaseInfo> ConnectionIndex { get; set; }
public AbpDatabaseInfoDictionary()
{
ConnectionIndex = new Dictionary<string, AbpDatabaseInfo>();
}
[CanBeNull]
public AbpDatabaseInfo GetMappedDatabaseOrNull(string connectionStringName)
{
return ConnectionIndex.GetOrDefault(connectionStringName);
}
public AbpDatabaseInfoDictionary Configure(string databaseName, Action<AbpDatabaseInfo> configureAction)
{
var databaseInfo = this.GetOrAdd(
databaseName,
() => new AbpDatabaseInfo(databaseName)
);
configureAction(databaseInfo);
return this;
}
/// <summary>
/// This method should be called if this dictionary changes.
/// It refreshes indexes for quick access to the connection informations.
/// </summary>
public void RefreshIndexes()
{
ConnectionIndex = new Dictionary<string, AbpDatabaseInfo>();
foreach (var databaseInfo in Values)
{
foreach (var mappedConnection in databaseInfo.MappedConnections)
{
if (ConnectionIndex.ContainsKey(mappedConnection))
{
throw new AbpException(
$"A connection name can not map to multiple databases: {mappedConnection}."
);
}
ConnectionIndex[mappedConnection] = databaseInfo;
}
}
}
}
}

44
framework/src/Volo.Abp.Data/Volo/Abp/Data/AbpDbConnectionOptions.cs

@ -1,12 +1,54 @@
namespace Volo.Abp.Data
using System;
using System.Collections.Generic;
namespace Volo.Abp.Data
{
public class AbpDbConnectionOptions
{
public ConnectionStrings ConnectionStrings { get; set; }
public AbpDatabaseInfoDictionary Databases { get; set; }
public AbpDbConnectionOptions()
{
ConnectionStrings = new ConnectionStrings();
Databases = new AbpDatabaseInfoDictionary();
}
public string GetConnectionStringOrNull(
string connectionStringName,
bool fallbackToDatabaseMappings = true,
bool fallbackToDefault = true)
{
var connectionString = ConnectionStrings.GetOrDefault(connectionStringName);
if (!connectionString.IsNullOrEmpty())
{
return connectionString;
}
if (fallbackToDatabaseMappings)
{
var database = Databases.GetMappedDatabaseOrNull(connectionStringName);
if (database != null)
{
connectionString = ConnectionStrings.GetOrDefault(database.DatabaseName);
if (!connectionString.IsNullOrEmpty())
{
return connectionString;
}
}
}
if (fallbackToDefault)
{
connectionString = ConnectionStrings.Default;
if (!connectionString.IsNullOrWhiteSpace())
{
return connectionString;
}
}
return null;
}
}
}

25
framework/src/Volo.Abp.Data/Volo/Abp/Data/DefaultConnectionStringResolver.cs

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
@ -10,7 +9,8 @@ namespace Volo.Abp.Data
{
protected AbpDbConnectionOptions Options { get; }
public DefaultConnectionStringResolver(IOptionsSnapshot<AbpDbConnectionOptions> options)
public DefaultConnectionStringResolver(
IOptionsSnapshot<AbpDbConnectionOptions> options)
{
Options = options.Value;
}
@ -28,18 +28,19 @@ namespace Volo.Abp.Data
private string ResolveInternal(string connectionStringName)
{
//Get module specific value if provided
if (!connectionStringName.IsNullOrEmpty())
if (connectionStringName == null)
{
var moduleConnString = Options.ConnectionStrings.GetOrDefault(connectionStringName);
if (!moduleConnString.IsNullOrEmpty())
{
return moduleConnString;
}
return Options.ConnectionStrings.Default;
}
var connectionString = Options.GetConnectionStringOrNull(connectionStringName);
if (!connectionString.IsNullOrEmpty())
{
return connectionString;
}
//Get default value
return Options.ConnectionStrings.Default;
return null;
}
}
}
}

30
framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/MultiTenantConnectionStringResolver.cs

@ -41,7 +41,7 @@ namespace Volo.Abp.MultiTenancy
}
var tenantDefaultConnectionString = tenant.ConnectionStrings.Default;
//Requesting default connection string...
if (connectionStringName == null ||
connectionStringName == ConnectionStrings.DefaultConnectionStringName)
@ -59,6 +59,18 @@ namespace Volo.Abp.MultiTenancy
//Found for the tenant
return connString;
}
//Fallback to the mapped database for the specific connection string
var database = Options.Databases.GetMappedDatabaseOrNull(connectionStringName);
if (database != null)
{
connString = tenant.ConnectionStrings.GetOrDefault(database.DatabaseName);
if (!connString.IsNullOrWhiteSpace())
{
//Found for the tenant
return connString;
}
}
//Fallback to tenant's default connection string if available
if (!tenantDefaultConnectionString.IsNullOrWhiteSpace())
@ -66,21 +78,7 @@ namespace Volo.Abp.MultiTenancy
return tenantDefaultConnectionString;
}
//Try to find the specific connection string for given name
var connStringInOptions = Options.ConnectionStrings.GetOrDefault(connectionStringName);
if (!connStringInOptions.IsNullOrWhiteSpace())
{
return connStringInOptions;
}
//Fallback to the global default connection string
var defaultConnectionString = Options.ConnectionStrings.Default;
if (!defaultConnectionString.IsNullOrWhiteSpace())
{
return defaultConnectionString;
}
throw new AbpException("No connection string defined!");
return await base.ResolveAsync(connectionStringName);
}
[Obsolete("Use ResolveAsync method.")]

Loading…
Cancel
Save