From c036a9d11f6f12027c47ea48611d161088ca8c55 Mon Sep 17 00:00:00 2001 From: Charles Nurse Date: Wed, 12 May 2021 15:17:40 -0700 Subject: [PATCH] Remove DbConfig and new constructors on DbContextBase and refactor Migrations to use explcit generation of IOqtaneDatabase instance --- Oqtane.Client/Modules/Admin/Sites/Add.razor | 1 - .../Databases/Interfaces/IMultiDatabase.cs | 2 +- .../DbContextOptionsBuilderExtensions.cs | 11 ---- .../OqtaneServiceCollectionExtensions.cs | 11 ---- .../Infrastructure/DatabaseManager.cs | 65 +++++++++---------- .../Migrations/01000000_InitializeMaster.cs | 2 +- .../Migrations/01000000_InitializeTenant.cs | 2 +- .../01000100_AddAdditionalIndexesInMaster.cs | 2 +- .../01000100_AddAdditionalIndexesInTenant.cs | 2 +- ...000101_AddAdditionColumnToNotifications.cs | 2 +- .../Migrations/01000201_DropColumnFromPage.cs | 2 +- ...2000001_AddColumnToProfileAndUpdatePage.cs | 2 +- .../02000101_UpdateIconColumnInPage.cs | 2 +- .../Migrations/02000102_AddLanguageTable.cs | 2 +- .../02000103_UpdatePageAndAddColumnToSite.cs | 2 +- .../Migrations/02000201_AddSiteGuidToSite.cs | 2 +- ...02_UpdateDefaultContainerTypeInSitePage.cs | 2 +- .../02000203_DropDefaultLayoutInSite.cs | 2 +- .../02010000_AddAppVersionsTableInTenant.cs | 2 +- ...2010000_AddIndexesForForeignKeyInMaster.cs | 2 +- .../02010001_AddDatabaseTypeColumnToTenant.cs | 2 +- .../Framework/MultiDatabaseMigration.cs | 8 +-- .../MultiDatabaseMigrationsAssembly.cs | 8 +-- .../HtmlText/Manager/HtmlTextManager.cs | 16 +++-- .../Migrations/01000000_InitializeModule.cs | 2 +- .../HtmlText/Repository/HtmlTextContext.cs | 5 +- .../Repository/Context/DBContextBase.cs | 59 +++-------------- Oqtane.Server/Repository/Context/DbConfig.cs | 27 -------- .../Repository/Context/MasterDBContext.cs | 45 +++++++------ .../Repository/Context/TenantDBContext.cs | 3 +- .../Repository/Interfaces/IDbConfig.cs | 20 ------ Oqtane.Server/Repository/SqlRepository.cs | 24 ++++--- Oqtane.Server/Startup.cs | 3 +- Oqtane.Shared/Shared/InstallConfig.cs | 20 ++++++ 34 files changed, 137 insertions(+), 225 deletions(-) delete mode 100644 Oqtane.Server/Repository/Context/DbConfig.cs delete mode 100644 Oqtane.Server/Repository/Interfaces/IDbConfig.cs diff --git a/Oqtane.Client/Modules/Admin/Sites/Add.razor b/Oqtane.Client/Modules/Admin/Sites/Add.razor index fde8e4e4..2be07b2c 100644 --- a/Oqtane.Client/Modules/Admin/Sites/Add.razor +++ b/Oqtane.Client/Modules/Admin/Sites/Add.razor @@ -11,7 +11,6 @@ @inject IInstallationService InstallationService @inject IDatabaseService DatabaseService @inject IStringLocalizer Localizer -@inject IEnumerable Databases @if (_tenants == null) { diff --git a/Oqtane.Server/Databases/Interfaces/IMultiDatabase.cs b/Oqtane.Server/Databases/Interfaces/IMultiDatabase.cs index 103cd76b..b150f9e1 100644 --- a/Oqtane.Server/Databases/Interfaces/IMultiDatabase.cs +++ b/Oqtane.Server/Databases/Interfaces/IMultiDatabase.cs @@ -5,6 +5,6 @@ namespace Oqtane.Repository.Databases.Interfaces { public interface IMultiDatabase { - public IEnumerable Databases { get; } + public IOqtaneDatabase ActiveDatabase { get; } } } diff --git a/Oqtane.Server/Extensions/DbContextOptionsBuilderExtensions.cs b/Oqtane.Server/Extensions/DbContextOptionsBuilderExtensions.cs index 41aa1de8..1c14cc8c 100644 --- a/Oqtane.Server/Extensions/DbContextOptionsBuilderExtensions.cs +++ b/Oqtane.Server/Extensions/DbContextOptionsBuilderExtensions.cs @@ -14,16 +14,5 @@ namespace Oqtane.Extensions return optionsBuilder; } - - public static DbContextOptionsBuilder UseOqtaneDatabase([NotNull] this DbContextOptionsBuilder optionsBuilder, string databaseType, string connectionString) - { - var type = Type.GetType(databaseType); - var database = Activator.CreateInstance(type) as IOqtaneDatabase; - - database.UseDatabase(optionsBuilder, connectionString); - - return optionsBuilder; - } - } } diff --git a/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs b/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs index 68306de5..def120af 100644 --- a/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs +++ b/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs @@ -47,17 +47,6 @@ namespace Microsoft.Extensions.DependencyInjection } } - // dynamically register database providers - var databaseTypes = assembly.GetInterfaces(); - foreach (var databaseType in databaseTypes) - { - if (databaseType.AssemblyQualifiedName != null) - { - var serviceType = Type.GetType("Oqtane.Interfaces.IOqtaneDatabase, Oqtane.Shared"); - services.AddScoped(serviceType ?? databaseType, databaseType); - } - } - // dynamically register hosted services var serviceTypes = assembly.GetTypes(hostedServiceType); foreach (var serviceType in serviceTypes) diff --git a/Oqtane.Server/Infrastructure/DatabaseManager.cs b/Oqtane.Server/Infrastructure/DatabaseManager.cs index 22becfcb..196d3630 100644 --- a/Oqtane.Server/Infrastructure/DatabaseManager.cs +++ b/Oqtane.Server/Infrastructure/DatabaseManager.cs @@ -30,6 +30,8 @@ namespace Oqtane.Infrastructure private readonly IServiceScopeFactory _serviceScopeFactory; private readonly IMemoryCache _cache; + private IOqtaneDatabase _database; + public DatabaseManager(IConfigurationRoot config, IServiceScopeFactory serviceScopeFactory, IMemoryCache cache) { _config = config; @@ -185,18 +187,12 @@ namespace Oqtane.Infrastructure var dataDirectory = AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString(); if (!Directory.Exists(dataDirectory)) Directory.CreateDirectory(dataDirectory ?? String.Empty); - var connectionString = NormalizeConnectionString(install.ConnectionString); - var databaseType = install.DatabaseType; - using (var scope = _serviceScopeFactory.CreateScope()) + var dbOptions = new DbContextOptionsBuilder().UseOqtaneDatabase(install.Database, NormalizeConnectionString(install.ConnectionString)).Options; + using (var dbc = new DbContext(dbOptions)) { - var databases = scope.ServiceProvider.GetServices(); - - using (var dbc = new DbContext(new DbContextOptionsBuilder().UseOqtaneDatabase(databases.Single(d => d.TypeName == databaseType), connectionString).Options)) - { - // create empty database if it does not exist - dbc.Database.EnsureCreated(); - result.Success = true; - } + // create empty database if it does not exist + dbc.Database.EnsureCreated(); + result.Success = true; } } catch (Exception ex) @@ -220,16 +216,16 @@ namespace Oqtane.Infrastructure { using (var scope = _serviceScopeFactory.CreateScope()) { - var databases = scope.ServiceProvider.GetServices(); var sql = scope.ServiceProvider.GetRequiredService(); + var installation = IsInstalled(); try { - var dbConfig = new DbConfig(null, null, databases) {ConnectionString = install.ConnectionString, DatabaseType = install.DatabaseType}; + UpdateConnectionString(install.ConnectionString); + UpdateDatabaseType(install.DatabaseType); - using (var masterDbContext = new MasterDBContext(new DbContextOptions(), dbConfig)) + using (var masterDbContext = new MasterDBContext(new DbContextOptions(), null, _config)) { - var installation = IsInstalled(); if (installation.Success && (install.DatabaseType == "SqlServer" || install.DatabaseType == "LocalDB")) { UpgradeSqlServer(sql, install.ConnectionString, install.DatabaseType, true); @@ -244,10 +240,10 @@ namespace Oqtane.Infrastructure result.Message = ex.Message; } - if (result.Success) + if (!result.Success) { - UpdateConnectionString(install.ConnectionString); - UpdateDatabaseType(install.DatabaseType); + UpdateConnectionString(String.Empty); + UpdateDatabaseType(String.Empty); } } } @@ -265,11 +261,7 @@ namespace Oqtane.Infrastructure if (!string.IsNullOrEmpty(install.TenantName) && !string.IsNullOrEmpty(install.Aliases)) { - using (var scope = _serviceScopeFactory.CreateScope()) - { - var databases = scope.ServiceProvider.GetServices(); - - using (var db = GetInstallationContext(databases)) + using (var db = GetInstallationContext()) { Tenant tenant; if (install.IsNewTenant) @@ -315,7 +307,6 @@ namespace Oqtane.Infrastructure _cache.Remove("aliases"); } - } } result.Success = true; @@ -332,19 +323,19 @@ namespace Oqtane.Infrastructure using (var scope = _serviceScopeFactory.CreateScope()) { var upgrades = scope.ServiceProvider.GetRequiredService(); - var databases = scope.ServiceProvider.GetServices(); var sql = scope.ServiceProvider.GetRequiredService(); + var tenantManager = scope.ServiceProvider.GetRequiredService(); - using (var db = GetInstallationContext(databases)) + using (var db = GetInstallationContext()) { foreach (var tenant in db.Tenant.ToList()) { + tenantManager.SetTenant(tenant.TenantId); try { - var dbConfig = new DbConfig(null, null, databases) {ConnectionString = tenant.DBConnectionString, DatabaseType = tenant.DBType}; - using (var tenantDbContext = new TenantDBContext(dbConfig, null)) + using (var tenantDbContext = new TenantDBContext(tenantManager, null)) { - if (dbConfig.DatabaseType == "SqlServer" || dbConfig.DatabaseType == "LocalDB") + if (install.DatabaseType == "SqlServer" || install.DatabaseType == "LocalDB") { UpgradeSqlServer(sql, tenant.DBConnectionString, tenant.DBType, false); } @@ -393,7 +384,6 @@ namespace Oqtane.Infrastructure { var moduleDefinitions = scope.ServiceProvider.GetRequiredService(); var sql = scope.ServiceProvider.GetRequiredService(); - var databases = scope.ServiceProvider.GetServices(); foreach (var moduleDefinition in moduleDefinitions.GetModuleDefinitions()) { @@ -403,7 +393,7 @@ namespace Oqtane.Infrastructure if (moduleType != null) { var versions = moduleDefinition.ReleaseVersions.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); - using (var db = GetInstallationContext(databases)) + using (var db = GetInstallationContext()) { foreach (var tenant in db.Tenant.ToList()) { @@ -591,12 +581,19 @@ namespace Oqtane.Infrastructure return connectionString; } - private InstallationContext GetInstallationContext(IEnumerable databases) + private InstallationContext GetInstallationContext() { + var connectionString = _config.GetConnectionString(SettingKeys.ConnectionStringKey); var databaseType = _config.GetSection(SettingKeys.DatabaseSection)[SettingKeys.DatabaseTypeKey]; - var connectionString = NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey)); + IOqtaneDatabase database = null; - return new InstallationContext(databases.Single(d => d.TypeName == databaseType), connectionString); + if (!String.IsNullOrEmpty(databaseType)) + { + var type = Type.GetType(databaseType); + database = Activator.CreateInstance(type) as IOqtaneDatabase; + } + + return new InstallationContext(database, connectionString); } private string GetInstallationConfig(string key, string defaultValue) diff --git a/Oqtane.Server/Migrations/01000000_InitializeMaster.cs b/Oqtane.Server/Migrations/01000000_InitializeMaster.cs index 1338686a..b6e3f964 100644 --- a/Oqtane.Server/Migrations/01000000_InitializeMaster.cs +++ b/Oqtane.Server/Migrations/01000000_InitializeMaster.cs @@ -11,7 +11,7 @@ namespace Oqtane.Migrations [Migration("Master.01.00.00.00")] public class InitializeMaster : MultiDatabaseMigration { - public InitializeMaster(IEnumerable databases) : base(databases) + public InitializeMaster(IOqtaneDatabase database) : base(database) { } diff --git a/Oqtane.Server/Migrations/01000000_InitializeTenant.cs b/Oqtane.Server/Migrations/01000000_InitializeTenant.cs index 79a41163..66905b4b 100644 --- a/Oqtane.Server/Migrations/01000000_InitializeTenant.cs +++ b/Oqtane.Server/Migrations/01000000_InitializeTenant.cs @@ -12,7 +12,7 @@ namespace Oqtane.Migrations [Migration("Tenant.01.00.00.00")] public class InitializeTenant : MultiDatabaseMigration { - public InitializeTenant(IEnumerable databases) : base(databases) + public InitializeTenant(IOqtaneDatabase database) : base(database) { } diff --git a/Oqtane.Server/Migrations/01000100_AddAdditionalIndexesInMaster.cs b/Oqtane.Server/Migrations/01000100_AddAdditionalIndexesInMaster.cs index a1ab6525..ef1380f7 100644 --- a/Oqtane.Server/Migrations/01000100_AddAdditionalIndexesInMaster.cs +++ b/Oqtane.Server/Migrations/01000100_AddAdditionalIndexesInMaster.cs @@ -11,7 +11,7 @@ namespace Oqtane.Migrations [Migration("Master.01.00.01.00")] public class AddAdditionalIndexesInMaster : MultiDatabaseMigration { - public AddAdditionalIndexesInMaster(IEnumerable databases) : base(databases) + public AddAdditionalIndexesInMaster(IOqtaneDatabase database) : base(database) { } diff --git a/Oqtane.Server/Migrations/01000100_AddAdditionalIndexesInTenant.cs b/Oqtane.Server/Migrations/01000100_AddAdditionalIndexesInTenant.cs index 6afdf29f..4fbf88f7 100644 --- a/Oqtane.Server/Migrations/01000100_AddAdditionalIndexesInTenant.cs +++ b/Oqtane.Server/Migrations/01000100_AddAdditionalIndexesInTenant.cs @@ -11,7 +11,7 @@ namespace Oqtane.Migrations [Migration("Tenant.01.00.01.00")] public class AddAdditionalIndexesInTenant : MultiDatabaseMigration { - public AddAdditionalIndexesInTenant(IEnumerable databases) : base(databases) + public AddAdditionalIndexesInTenant(IOqtaneDatabase database) : base(database) { } diff --git a/Oqtane.Server/Migrations/01000101_AddAdditionColumnToNotifications.cs b/Oqtane.Server/Migrations/01000101_AddAdditionColumnToNotifications.cs index f41cb26e..a20389db 100644 --- a/Oqtane.Server/Migrations/01000101_AddAdditionColumnToNotifications.cs +++ b/Oqtane.Server/Migrations/01000101_AddAdditionColumnToNotifications.cs @@ -11,7 +11,7 @@ namespace Oqtane.Migrations [Migration("Tenant.01.00.01.01")] public class AddAdditionColumnToNotifications : MultiDatabaseMigration { - public AddAdditionColumnToNotifications(IEnumerable databases) : base(databases) + public AddAdditionColumnToNotifications(IOqtaneDatabase database) : base(database) { } diff --git a/Oqtane.Server/Migrations/01000201_DropColumnFromPage.cs b/Oqtane.Server/Migrations/01000201_DropColumnFromPage.cs index 5f5fee65..276f6256 100644 --- a/Oqtane.Server/Migrations/01000201_DropColumnFromPage.cs +++ b/Oqtane.Server/Migrations/01000201_DropColumnFromPage.cs @@ -11,7 +11,7 @@ namespace Oqtane.Migrations [Migration("Tenant.01.00.02.01")] public class DropColumnFromPage : MultiDatabaseMigration { - public DropColumnFromPage(IEnumerable databases) : base(databases) + public DropColumnFromPage(IOqtaneDatabase database) : base(database) { } diff --git a/Oqtane.Server/Migrations/02000001_AddColumnToProfileAndUpdatePage.cs b/Oqtane.Server/Migrations/02000001_AddColumnToProfileAndUpdatePage.cs index d7a13fb2..8cad32c9 100644 --- a/Oqtane.Server/Migrations/02000001_AddColumnToProfileAndUpdatePage.cs +++ b/Oqtane.Server/Migrations/02000001_AddColumnToProfileAndUpdatePage.cs @@ -11,7 +11,7 @@ namespace Oqtane.Migrations [Migration("Tenant.02.00.00.01")] public class AddColumnToProfileAndUpdatePage : MultiDatabaseMigration { - public AddColumnToProfileAndUpdatePage(IEnumerable databases) : base(databases) + public AddColumnToProfileAndUpdatePage(IOqtaneDatabase database) : base(database) { } diff --git a/Oqtane.Server/Migrations/02000101_UpdateIconColumnInPage.cs b/Oqtane.Server/Migrations/02000101_UpdateIconColumnInPage.cs index f0dfd972..36fa11af 100644 --- a/Oqtane.Server/Migrations/02000101_UpdateIconColumnInPage.cs +++ b/Oqtane.Server/Migrations/02000101_UpdateIconColumnInPage.cs @@ -11,7 +11,7 @@ namespace Oqtane.Migrations [Migration("Tenant.02.00.01.01")] public class UpdateIconColumnInPage : MultiDatabaseMigration { - public UpdateIconColumnInPage(IEnumerable databases) : base(databases) + public UpdateIconColumnInPage(IOqtaneDatabase database) : base(database) { } diff --git a/Oqtane.Server/Migrations/02000102_AddLanguageTable.cs b/Oqtane.Server/Migrations/02000102_AddLanguageTable.cs index 0fa1b490..75f5b4dc 100644 --- a/Oqtane.Server/Migrations/02000102_AddLanguageTable.cs +++ b/Oqtane.Server/Migrations/02000102_AddLanguageTable.cs @@ -11,7 +11,7 @@ namespace Oqtane.Migrations [Migration("Tenant.02.00.01.02")] public class AddLanguageTable : MultiDatabaseMigration { - public AddLanguageTable(IEnumerable databases) : base(databases) + public AddLanguageTable(IOqtaneDatabase database) : base(database) { } diff --git a/Oqtane.Server/Migrations/02000103_UpdatePageAndAddColumnToSite.cs b/Oqtane.Server/Migrations/02000103_UpdatePageAndAddColumnToSite.cs index 740b671a..9fca1d97 100644 --- a/Oqtane.Server/Migrations/02000103_UpdatePageAndAddColumnToSite.cs +++ b/Oqtane.Server/Migrations/02000103_UpdatePageAndAddColumnToSite.cs @@ -11,7 +11,7 @@ namespace Oqtane.Migrations [Migration("Tenant.02.00.01.03")] public class UpdatePageAndAddColumnToSite : MultiDatabaseMigration { - public UpdatePageAndAddColumnToSite(IEnumerable databases) : base(databases) + public UpdatePageAndAddColumnToSite(IOqtaneDatabase database) : base(database) { } diff --git a/Oqtane.Server/Migrations/02000201_AddSiteGuidToSite.cs b/Oqtane.Server/Migrations/02000201_AddSiteGuidToSite.cs index 45484d92..d8cd94e7 100644 --- a/Oqtane.Server/Migrations/02000201_AddSiteGuidToSite.cs +++ b/Oqtane.Server/Migrations/02000201_AddSiteGuidToSite.cs @@ -12,7 +12,7 @@ namespace Oqtane.Migrations public class AddSiteGuidToSite : MultiDatabaseMigration { - public AddSiteGuidToSite(IEnumerable databases) : base(databases) + public AddSiteGuidToSite(IOqtaneDatabase database) : base(database) { } diff --git a/Oqtane.Server/Migrations/02000202_UpdateDefaultContainerTypeInSitePage.cs b/Oqtane.Server/Migrations/02000202_UpdateDefaultContainerTypeInSitePage.cs index 88d63706..3c605038 100644 --- a/Oqtane.Server/Migrations/02000202_UpdateDefaultContainerTypeInSitePage.cs +++ b/Oqtane.Server/Migrations/02000202_UpdateDefaultContainerTypeInSitePage.cs @@ -11,7 +11,7 @@ namespace Oqtane.Migrations [Migration("Tenant.02.00.02.02")] public class UpdateDefaultContainerTypeInSitePage : MultiDatabaseMigration { - public UpdateDefaultContainerTypeInSitePage(IEnumerable databases) : base(databases) + public UpdateDefaultContainerTypeInSitePage(IOqtaneDatabase database) : base(database) { } diff --git a/Oqtane.Server/Migrations/02000203_DropDefaultLayoutInSite.cs b/Oqtane.Server/Migrations/02000203_DropDefaultLayoutInSite.cs index 679b0bac..adda1079 100644 --- a/Oqtane.Server/Migrations/02000203_DropDefaultLayoutInSite.cs +++ b/Oqtane.Server/Migrations/02000203_DropDefaultLayoutInSite.cs @@ -11,7 +11,7 @@ namespace Oqtane.Migrations [Migration("Tenant.02.00.02.03")] public class DropDefaultLayoutInSite : MultiDatabaseMigration { - public DropDefaultLayoutInSite(IEnumerable databases) : base(databases) + public DropDefaultLayoutInSite(IOqtaneDatabase database) : base(database) { } diff --git a/Oqtane.Server/Migrations/02010000_AddAppVersionsTableInTenant.cs b/Oqtane.Server/Migrations/02010000_AddAppVersionsTableInTenant.cs index dfaeea21..682c1b13 100644 --- a/Oqtane.Server/Migrations/02010000_AddAppVersionsTableInTenant.cs +++ b/Oqtane.Server/Migrations/02010000_AddAppVersionsTableInTenant.cs @@ -12,7 +12,7 @@ namespace Oqtane.Migrations [Migration("Tenant.02.01.00.00")] public class AddAppVersionsTable : MultiDatabaseMigration { - public AddAppVersionsTable(IEnumerable databases) : base(databases) + public AddAppVersionsTable(IOqtaneDatabase database) : base(database) { } diff --git a/Oqtane.Server/Migrations/02010000_AddIndexesForForeignKeyInMaster.cs b/Oqtane.Server/Migrations/02010000_AddIndexesForForeignKeyInMaster.cs index 5828f962..c5fdd1b9 100644 --- a/Oqtane.Server/Migrations/02010000_AddIndexesForForeignKeyInMaster.cs +++ b/Oqtane.Server/Migrations/02010000_AddIndexesForForeignKeyInMaster.cs @@ -11,7 +11,7 @@ namespace Oqtane.Migrations [Migration("Master.02.01.00.00")] public class AddIndexesForForeignKeyInMaster : MultiDatabaseMigration { - public AddIndexesForForeignKeyInMaster(IEnumerable databases) : base(databases) + public AddIndexesForForeignKeyInMaster(IOqtaneDatabase database) : base(database) { } diff --git a/Oqtane.Server/Migrations/02010001_AddDatabaseTypeColumnToTenant.cs b/Oqtane.Server/Migrations/02010001_AddDatabaseTypeColumnToTenant.cs index f57b302f..73937171 100644 --- a/Oqtane.Server/Migrations/02010001_AddDatabaseTypeColumnToTenant.cs +++ b/Oqtane.Server/Migrations/02010001_AddDatabaseTypeColumnToTenant.cs @@ -11,7 +11,7 @@ namespace Oqtane.Migrations [Migration("Master.02.01.00.01")] public class AddDatabaseTypeColumnToTenant : MultiDatabaseMigration { - public AddDatabaseTypeColumnToTenant(IEnumerable databases) : base(databases) + public AddDatabaseTypeColumnToTenant(IOqtaneDatabase database) : base(database) { } diff --git a/Oqtane.Server/Migrations/Framework/MultiDatabaseMigration.cs b/Oqtane.Server/Migrations/Framework/MultiDatabaseMigration.cs index ca9a0217..52c44623 100644 --- a/Oqtane.Server/Migrations/Framework/MultiDatabaseMigration.cs +++ b/Oqtane.Server/Migrations/Framework/MultiDatabaseMigration.cs @@ -7,14 +7,14 @@ namespace Oqtane.Migrations { public abstract class MultiDatabaseMigration : Migration { - private readonly IEnumerable _databases; + private readonly IOqtaneDatabase _databases; - protected MultiDatabaseMigration(IEnumerable databases) + protected MultiDatabaseMigration(IOqtaneDatabase database) { - _databases = databases; + ActiveDatabase = database; } - protected IOqtaneDatabase ActiveDatabase => _databases.FirstOrDefault(d => d.Provider == ActiveProvider); + protected IOqtaneDatabase ActiveDatabase { get; } protected string RewriteName(string name) { diff --git a/Oqtane.Server/Migrations/Framework/MultiDatabaseMigrationsAssembly.cs b/Oqtane.Server/Migrations/Framework/MultiDatabaseMigrationsAssembly.cs index 6373f351..73117e20 100644 --- a/Oqtane.Server/Migrations/Framework/MultiDatabaseMigrationsAssembly.cs +++ b/Oqtane.Server/Migrations/Framework/MultiDatabaseMigrationsAssembly.cs @@ -13,7 +13,7 @@ namespace Oqtane.Migrations.Framework { public class MultiDatabaseMigrationsAssembly: MigrationsAssembly { - private readonly IEnumerable _databases; + private readonly IOqtaneDatabase _database; public MultiDatabaseMigrationsAssembly( ICurrentDbContext currentContext, @@ -23,15 +23,15 @@ namespace Oqtane.Migrations.Framework : base(currentContext, options, idGenerator, logger) { var multiDatabaseContext = currentContext.Context as IMultiDatabase; - if (multiDatabaseContext != null) _databases = multiDatabaseContext.Databases; + if (multiDatabaseContext != null) _database = multiDatabaseContext.ActiveDatabase; } public override Migration CreateMigration(TypeInfo migrationClass, string activeProvider) { - var hasCtorWithCacheOptions = migrationClass.GetConstructor(new[] { typeof(IEnumerable) }) != null; + var hasCtorWithCacheOptions = migrationClass.GetConstructor(new[] { typeof(IOqtaneDatabase) }) != null; if (hasCtorWithCacheOptions) { - var migration = (Migration)Activator.CreateInstance(migrationClass.AsType(), _databases); + var migration = (Migration)Activator.CreateInstance(migrationClass.AsType(), _database); if (migration != null) { migration.ActiveProvider = activeProvider; diff --git a/Oqtane.Server/Modules/HtmlText/Manager/HtmlTextManager.cs b/Oqtane.Server/Modules/HtmlText/Manager/HtmlTextManager.cs index 40f7bde4..a741f823 100644 --- a/Oqtane.Server/Modules/HtmlText/Manager/HtmlTextManager.cs +++ b/Oqtane.Server/Modules/HtmlText/Manager/HtmlTextManager.cs @@ -6,6 +6,7 @@ using Oqtane.Repository; using Oqtane.Modules.HtmlText.Models; using Oqtane.Modules.HtmlText.Repository; using System.Net; +using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Oqtane.Enums; @@ -18,12 +19,15 @@ namespace Oqtane.Modules.HtmlText.Manager public class HtmlTextManager : MigratableModuleBase, IInstallable, IPortable { private readonly IHtmlTextRepository _htmlText; - private readonly IEnumerable _databases; + private readonly ITenantManager _tenantManager; + private readonly IHttpContextAccessor _accessor; - public HtmlTextManager(IHtmlTextRepository htmlText, IEnumerable databases) + + public HtmlTextManager(IHtmlTextRepository htmlText, ITenantManager tenantManager, IHttpContextAccessor httpContextAccessor) { _htmlText = htmlText; - _databases = databases; + _tenantManager = tenantManager; + _accessor = httpContextAccessor; } public string ExportModule(Module module) @@ -57,14 +61,12 @@ namespace Oqtane.Modules.HtmlText.Manager public bool Install(Tenant tenant, string version) { - var dbConfig = new DbConfig(null, null, _databases) {ConnectionString = tenant.DBConnectionString, DatabaseType = tenant.DBType}; - return Migrate(new HtmlTextContext(dbConfig, null), tenant, MigrationType.Up); + return Migrate(new HtmlTextContext(_tenantManager, _accessor), tenant, MigrationType.Up); } public bool Uninstall(Tenant tenant) { - var dbConfig = new DbConfig(null, null, _databases) {ConnectionString = tenant.DBConnectionString, DatabaseType = tenant.DBType}; - return Migrate(new HtmlTextContext(dbConfig, null), tenant, MigrationType.Down); + return Migrate(new HtmlTextContext(_tenantManager, _accessor), tenant, MigrationType.Down); } } } diff --git a/Oqtane.Server/Modules/HtmlText/Migrations/01000000_InitializeModule.cs b/Oqtane.Server/Modules/HtmlText/Migrations/01000000_InitializeModule.cs index 5ed5242c..da248e9d 100644 --- a/Oqtane.Server/Modules/HtmlText/Migrations/01000000_InitializeModule.cs +++ b/Oqtane.Server/Modules/HtmlText/Migrations/01000000_InitializeModule.cs @@ -12,7 +12,7 @@ namespace Oqtane.Modules.HtmlText.Migrations [Migration("HtmlText.01.00.00.00")] public class InitializeModule : MultiDatabaseMigration { - public InitializeModule(IEnumerable databases) : base(databases) + public InitializeModule(IOqtaneDatabase database) : base(database) { } diff --git a/Oqtane.Server/Modules/HtmlText/Repository/HtmlTextContext.cs b/Oqtane.Server/Modules/HtmlText/Repository/HtmlTextContext.cs index 10199b8d..0232cd43 100644 --- a/Oqtane.Server/Modules/HtmlText/Repository/HtmlTextContext.cs +++ b/Oqtane.Server/Modules/HtmlText/Repository/HtmlTextContext.cs @@ -1,3 +1,4 @@ +using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Oqtane.Infrastructure; using Oqtane.Repository; @@ -10,9 +11,7 @@ namespace Oqtane.Modules.HtmlText.Repository { public class HtmlTextContext : DBContextBase, IService, IMultiDatabase { - public HtmlTextContext(IDbConfig dbConfig, ITenantManager tenantManager) : base(dbConfig, tenantManager) - { - } + public HtmlTextContext(ITenantManager tenantManager, IHttpContextAccessor httpContextAccessor) : base(tenantManager, httpContextAccessor) { } public virtual DbSet HtmlText { get; set; } } diff --git a/Oqtane.Server/Repository/Context/DBContextBase.cs b/Oqtane.Server/Repository/Context/DBContextBase.cs index ae0e50fd..d9786546 100644 --- a/Oqtane.Server/Repository/Context/DBContextBase.cs +++ b/Oqtane.Server/Repository/Context/DBContextBase.cs @@ -23,7 +23,6 @@ namespace Oqtane.Repository private readonly ITenantResolver _tenantResolver; private readonly ITenantManager _tenantManager; private readonly IHttpContextAccessor _accessor; - private readonly IConfiguration _configuration; private string _connectionString; private string _databaseType; @@ -34,17 +33,7 @@ namespace Oqtane.Repository _accessor = httpContextAccessor; } - public DBContextBase(IDbConfig dbConfig, ITenantManager tenantManager) - { - _accessor = dbConfig.Accessor; - _configuration = dbConfig.Configuration; - _connectionString = dbConfig.ConnectionString; - _databaseType = dbConfig.DatabaseType; - Databases = dbConfig.Databases; - _tenantManager = tenantManager; - } - - public IEnumerable Databases { get; } + public IOqtaneDatabase ActiveDatabase { get; private set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { @@ -69,27 +58,17 @@ namespace Oqtane.Repository .Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString()); _databaseType = tenant.DBType; } - else - { - if (!String.IsNullOrEmpty(_configuration.GetConnectionString("DefaultConnection"))) - { - _connectionString = _configuration.GetConnectionString("DefaultConnection") - .Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString()); - } - _databaseType = _configuration.GetSection(SettingKeys.DatabaseSection)[SettingKeys.DatabaseTypeKey]; - } } - if (!string.IsNullOrEmpty(_connectionString) && !string.IsNullOrEmpty(_databaseType)) + if (!String.IsNullOrEmpty(_databaseType)) { - if (Databases != null) - { - optionsBuilder.UseOqtaneDatabase(Databases.Single(d => d.TypeName == _databaseType), _connectionString); - } - else - { - optionsBuilder.UseOqtaneDatabase(_databaseType, _connectionString); - } + var type = Type.GetType(_databaseType); + ActiveDatabase = Activator.CreateInstance(type) as IOqtaneDatabase; + } + + if (!string.IsNullOrEmpty(_connectionString) && ActiveDatabase != null) + { + optionsBuilder.UseOqtaneDatabase(ActiveDatabase, _connectionString); } base.OnConfiguring(optionsBuilder); @@ -99,13 +78,7 @@ namespace Oqtane.Repository { base.OnModelCreating(builder); - if (Databases != null) - { - var database = Databases.Single(d => d.TypeName == _databaseType); - - database.UpdateIdentityStoreTableNames(builder); - } - + ActiveDatabase.UpdateIdentityStoreTableNames(builder); } public override int SaveChanges() @@ -122,17 +95,5 @@ namespace Oqtane.Repository _tenantResolver = tenantResolver; _accessor = httpContextAccessor; } - - [Obsolete("This constructor is obsolete. Use DBContextBase(IDbConfig dbConfig, ITenantManager tenantManager) instead.", false)] - public DBContextBase(IDbConfig dbConfig, ITenantResolver tenantResolver) - { - _accessor = dbConfig.Accessor; - _configuration = dbConfig.Configuration; - _connectionString = dbConfig.ConnectionString; - _databaseType = dbConfig.DatabaseType; - Databases = dbConfig.Databases; - _tenantResolver = tenantResolver; - } - } } diff --git a/Oqtane.Server/Repository/Context/DbConfig.cs b/Oqtane.Server/Repository/Context/DbConfig.cs deleted file mode 100644 index 97e60f8f..00000000 --- a/Oqtane.Server/Repository/Context/DbConfig.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Collections.Generic; -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.Configuration; -using Oqtane.Interfaces; - -namespace Oqtane.Repository -{ - public class DbConfig : IDbConfig - { - public DbConfig(IHttpContextAccessor accessor, IConfiguration configuration, IEnumerable databases) - { - Accessor = accessor; - Configuration = configuration; - Databases = databases; - } - - public IHttpContextAccessor Accessor { get; } - - public IConfiguration Configuration { get; } - - public IEnumerable Databases { get; set; } - - public string ConnectionString { get; set; } - - public string DatabaseType { get; set; } - } -} diff --git a/Oqtane.Server/Repository/Context/MasterDBContext.cs b/Oqtane.Server/Repository/Context/MasterDBContext.cs index c5c8274e..9520f9a1 100644 --- a/Oqtane.Server/Repository/Context/MasterDBContext.cs +++ b/Oqtane.Server/Repository/Context/MasterDBContext.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Migrations; using Oqtane.Models; @@ -19,45 +20,43 @@ namespace Oqtane.Repository { public class MasterDBContext : DbContext, IMultiDatabase { - private readonly IDbConfig _dbConfig; + private readonly IHttpContextAccessor _accessor; + private readonly IConfiguration _configuration; + private string _connectionString; + private string _databaseType; - public MasterDBContext(DbContextOptions options, IDbConfig dbConfig) : base(options) + public MasterDBContext(DbContextOptions options, IHttpContextAccessor accessor, IConfiguration configuration) : base(options) { - _dbConfig = dbConfig; - Databases = dbConfig.Databases; + _accessor = accessor; + _configuration = configuration; } - public IEnumerable Databases { get; } + public IOqtaneDatabase ActiveDatabase { get; private set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.ReplaceService(); - var connectionString = _dbConfig.ConnectionString; - var configuration = _dbConfig.Configuration; - var databaseType = _dbConfig.DatabaseType; - - if(string.IsNullOrEmpty(connectionString) && configuration != null) + if(_configuration != null) { - if (!String.IsNullOrEmpty(configuration.GetConnectionString("DefaultConnection"))) + if (!String.IsNullOrEmpty(_configuration.GetConnectionString("DefaultConnection"))) { - connectionString = configuration.GetConnectionString("DefaultConnection") + _connectionString = _configuration.GetConnectionString("DefaultConnection") .Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString()); } - databaseType = configuration.GetSection(SettingKeys.DatabaseSection)[SettingKeys.DatabaseTypeKey]; + _databaseType = _configuration.GetSection(SettingKeys.DatabaseSection)[SettingKeys.DatabaseTypeKey]; } - if (!string.IsNullOrEmpty(connectionString) && !string.IsNullOrEmpty(databaseType)) + if (!String.IsNullOrEmpty(_databaseType)) { - if (Databases != null) - { - optionsBuilder.UseOqtaneDatabase(Databases.Single(d => d.TypeName == databaseType), connectionString); - } - else - { - optionsBuilder.UseOqtaneDatabase(databaseType, connectionString); - } + var type = Type.GetType(_databaseType); + ActiveDatabase = Activator.CreateInstance(type) as IOqtaneDatabase; + } + + if (!string.IsNullOrEmpty(_connectionString) && ActiveDatabase != null) + { + optionsBuilder.UseOqtaneDatabase(ActiveDatabase, _connectionString); } base.OnConfiguring(optionsBuilder); @@ -71,7 +70,7 @@ namespace Oqtane.Repository public override int SaveChanges() { - DbContextUtils.SaveChanges(this, _dbConfig.Accessor); + DbContextUtils.SaveChanges(this, _accessor); return base.SaveChanges(); } diff --git a/Oqtane.Server/Repository/Context/TenantDBContext.cs b/Oqtane.Server/Repository/Context/TenantDBContext.cs index f4d554c0..ca8c822d 100644 --- a/Oqtane.Server/Repository/Context/TenantDBContext.cs +++ b/Oqtane.Server/Repository/Context/TenantDBContext.cs @@ -1,3 +1,4 @@ +using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Oqtane.Infrastructure; using Oqtane.Models; @@ -11,7 +12,7 @@ namespace Oqtane.Repository { public class TenantDBContext : DBContextBase, IMultiDatabase { - public TenantDBContext(IDbConfig dbConfig, ITenantManager tenantManager) : base(dbConfig, tenantManager) { } + public TenantDBContext(ITenantManager tenantManager, IHttpContextAccessor httpContextAccessor) : base(tenantManager, httpContextAccessor) { } public virtual DbSet Site { get; set; } public virtual DbSet Page { get; set; } diff --git a/Oqtane.Server/Repository/Interfaces/IDbConfig.cs b/Oqtane.Server/Repository/Interfaces/IDbConfig.cs deleted file mode 100644 index 2d364505..00000000 --- a/Oqtane.Server/Repository/Interfaces/IDbConfig.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Collections.Generic; -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.Configuration; -using Oqtane.Interfaces; - -namespace Oqtane.Repository -{ - public interface IDbConfig - { - public IHttpContextAccessor Accessor { get; } - - public IConfiguration Configuration { get; } - - public IEnumerable Databases { get; set; } - - public string ConnectionString { get; set; } - - public string DatabaseType { get; set; } - } -} diff --git a/Oqtane.Server/Repository/SqlRepository.cs b/Oqtane.Server/Repository/SqlRepository.cs index c2b6ed3f..aad0700c 100644 --- a/Oqtane.Server/Repository/SqlRepository.cs +++ b/Oqtane.Server/Repository/SqlRepository.cs @@ -14,13 +14,6 @@ namespace Oqtane.Repository { public class SqlRepository : ISqlRepository { - private IEnumerable _databases; - - public SqlRepository(IEnumerable databases) - { - _databases = databases; - } - public void ExecuteScript(Tenant tenant, string script) { // execute script in current tenant @@ -80,14 +73,13 @@ namespace Oqtane.Repository public IDataReader ExecuteReader(Tenant tenant, string query) { - var db = _databases.Single(d => d.TypeName == tenant.DBType); + var db = GetActiveDatabase(tenant.DBType); return db.ExecuteReader(tenant.DBConnectionString, query); } private int ExecuteNonQuery(string connectionString, string databaseType, string query) { - var db = _databases.Single(d => d.TypeName == databaseType); - + var db = GetActiveDatabase(databaseType); return db.ExecuteNonQuery(connectionString, query); } @@ -114,5 +106,17 @@ namespace Oqtane.Repository return script; } + + private IOqtaneDatabase GetActiveDatabase(string databaseType) + { + IOqtaneDatabase activeDatabase = null; + if (!String.IsNullOrEmpty(databaseType)) + { + var type = Type.GetType(databaseType); + activeDatabase = Activator.CreateInstance(type) as IOqtaneDatabase; + } + + return activeDatabase; + } } } diff --git a/Oqtane.Server/Startup.cs b/Oqtane.Server/Startup.cs index f33a6e91..8f21243f 100644 --- a/Oqtane.Server/Startup.cs +++ b/Oqtane.Server/Startup.cs @@ -206,11 +206,10 @@ namespace Oqtane services.AddTransient(); services.AddTransient(); // obsolete - replaced by ITenantManager - services.AddTransient(); + services.AddTransient(); // load the external assemblies into the app domain, install services services.AddOqtane(_runtime, _supportedCultures); - services.AddScoped(); services.AddDbContext(options => { }); services.AddDbContext(options => { }); diff --git a/Oqtane.Shared/Shared/InstallConfig.cs b/Oqtane.Shared/Shared/InstallConfig.cs index 2669431c..26d66252 100644 --- a/Oqtane.Shared/Shared/InstallConfig.cs +++ b/Oqtane.Shared/Shared/InstallConfig.cs @@ -1,9 +1,29 @@ +using System; +using Oqtane.Interfaces; + namespace Oqtane.Shared { public class InstallConfig { + private IOqtaneDatabase _database; + public string ConnectionString { get; set; } public string DatabaseType { get; set; } + + public IOqtaneDatabase Database + { + get + { + if (_database == null) + { + var type = Type.GetType(DatabaseType); + _database = Activator.CreateInstance(type) as IOqtaneDatabase; + } + + return _database; + } + } + public string Aliases { get; set; } public string TenantName { get; set; } public bool IsNewTenant { get; set; }