Remove DbConfig and new constructors on DbContextBase and refactor Migrations to use explcit generation of IOqtaneDatabase instance

This commit is contained in:
Charles Nurse 2021-05-12 15:17:40 -07:00
parent c958f90ee2
commit c036a9d11f
34 changed files with 137 additions and 225 deletions

View File

@ -11,7 +11,6 @@
@inject IInstallationService InstallationService
@inject IDatabaseService DatabaseService
@inject IStringLocalizer<Add> Localizer
@inject IEnumerable<IOqtaneDatabase> Databases
@if (_tenants == null)
{

View File

@ -5,6 +5,6 @@ namespace Oqtane.Repository.Databases.Interfaces
{
public interface IMultiDatabase
{
public IEnumerable<IOqtaneDatabase> Databases { get; }
public IOqtaneDatabase ActiveDatabase { get; }
}
}

View File

@ -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;
}
}
}

View File

@ -47,17 +47,6 @@ namespace Microsoft.Extensions.DependencyInjection
}
}
// dynamically register database providers
var databaseTypes = assembly.GetInterfaces<IOqtaneDatabase>();
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)

View File

@ -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,20 +187,14 @@ 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 databases = scope.ServiceProvider.GetServices<IOqtaneDatabase>();
using (var dbc = new DbContext(new DbContextOptionsBuilder().UseOqtaneDatabase(databases.Single(d => d.TypeName == databaseType), connectionString).Options))
var dbOptions = new DbContextOptionsBuilder().UseOqtaneDatabase(install.Database, NormalizeConnectionString(install.ConnectionString)).Options;
using (var dbc = new DbContext(dbOptions))
{
// create empty database if it does not exist
dbc.Database.EnsureCreated();
result.Success = true;
}
}
}
catch (Exception ex)
{
result.Message = ex.Message;
@ -220,16 +216,16 @@ namespace Oqtane.Infrastructure
{
using (var scope = _serviceScopeFactory.CreateScope())
{
var databases = scope.ServiceProvider.GetServices<IOqtaneDatabase>();
var sql = scope.ServiceProvider.GetRequiredService<ISqlRepository>();
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<MasterDBContext>(), dbConfig))
using (var masterDbContext = new MasterDBContext(new DbContextOptions<MasterDBContext>(), 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<IOqtaneDatabase>();
using (var db = GetInstallationContext(databases))
using (var db = GetInstallationContext())
{
Tenant tenant;
if (install.IsNewTenant)
@ -316,7 +308,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<IUpgradeManager>();
var databases = scope.ServiceProvider.GetServices<IOqtaneDatabase>();
var sql = scope.ServiceProvider.GetRequiredService<ISqlRepository>();
var tenantManager = scope.ServiceProvider.GetRequiredService<ITenantManager>();
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<IModuleDefinitionRepository>();
var sql = scope.ServiceProvider.GetRequiredService<ISqlRepository>();
var databases = scope.ServiceProvider.GetServices<IOqtaneDatabase>();
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<IOqtaneDatabase> 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)

View File

@ -11,7 +11,7 @@ namespace Oqtane.Migrations
[Migration("Master.01.00.00.00")]
public class InitializeMaster : MultiDatabaseMigration
{
public InitializeMaster(IEnumerable<IOqtaneDatabase> databases) : base(databases)
public InitializeMaster(IOqtaneDatabase database) : base(database)
{
}

View File

@ -12,7 +12,7 @@ namespace Oqtane.Migrations
[Migration("Tenant.01.00.00.00")]
public class InitializeTenant : MultiDatabaseMigration
{
public InitializeTenant(IEnumerable<IOqtaneDatabase> databases) : base(databases)
public InitializeTenant(IOqtaneDatabase database) : base(database)
{
}

View File

@ -11,7 +11,7 @@ namespace Oqtane.Migrations
[Migration("Master.01.00.01.00")]
public class AddAdditionalIndexesInMaster : MultiDatabaseMigration
{
public AddAdditionalIndexesInMaster(IEnumerable<IOqtaneDatabase> databases) : base(databases)
public AddAdditionalIndexesInMaster(IOqtaneDatabase database) : base(database)
{
}

View File

@ -11,7 +11,7 @@ namespace Oqtane.Migrations
[Migration("Tenant.01.00.01.00")]
public class AddAdditionalIndexesInTenant : MultiDatabaseMigration
{
public AddAdditionalIndexesInTenant(IEnumerable<IOqtaneDatabase> databases) : base(databases)
public AddAdditionalIndexesInTenant(IOqtaneDatabase database) : base(database)
{
}

View File

@ -11,7 +11,7 @@ namespace Oqtane.Migrations
[Migration("Tenant.01.00.01.01")]
public class AddAdditionColumnToNotifications : MultiDatabaseMigration
{
public AddAdditionColumnToNotifications(IEnumerable<IOqtaneDatabase> databases) : base(databases)
public AddAdditionColumnToNotifications(IOqtaneDatabase database) : base(database)
{
}

View File

@ -11,7 +11,7 @@ namespace Oqtane.Migrations
[Migration("Tenant.01.00.02.01")]
public class DropColumnFromPage : MultiDatabaseMigration
{
public DropColumnFromPage(IEnumerable<IOqtaneDatabase> databases) : base(databases)
public DropColumnFromPage(IOqtaneDatabase database) : base(database)
{
}

View File

@ -11,7 +11,7 @@ namespace Oqtane.Migrations
[Migration("Tenant.02.00.00.01")]
public class AddColumnToProfileAndUpdatePage : MultiDatabaseMigration
{
public AddColumnToProfileAndUpdatePage(IEnumerable<IOqtaneDatabase> databases) : base(databases)
public AddColumnToProfileAndUpdatePage(IOqtaneDatabase database) : base(database)
{
}

View File

@ -11,7 +11,7 @@ namespace Oqtane.Migrations
[Migration("Tenant.02.00.01.01")]
public class UpdateIconColumnInPage : MultiDatabaseMigration
{
public UpdateIconColumnInPage(IEnumerable<IOqtaneDatabase> databases) : base(databases)
public UpdateIconColumnInPage(IOqtaneDatabase database) : base(database)
{
}

View File

@ -11,7 +11,7 @@ namespace Oqtane.Migrations
[Migration("Tenant.02.00.01.02")]
public class AddLanguageTable : MultiDatabaseMigration
{
public AddLanguageTable(IEnumerable<IOqtaneDatabase> databases) : base(databases)
public AddLanguageTable(IOqtaneDatabase database) : base(database)
{
}

View File

@ -11,7 +11,7 @@ namespace Oqtane.Migrations
[Migration("Tenant.02.00.01.03")]
public class UpdatePageAndAddColumnToSite : MultiDatabaseMigration
{
public UpdatePageAndAddColumnToSite(IEnumerable<IOqtaneDatabase> databases) : base(databases)
public UpdatePageAndAddColumnToSite(IOqtaneDatabase database) : base(database)
{
}

View File

@ -12,7 +12,7 @@ namespace Oqtane.Migrations
public class AddSiteGuidToSite : MultiDatabaseMigration
{
public AddSiteGuidToSite(IEnumerable<IOqtaneDatabase> databases) : base(databases)
public AddSiteGuidToSite(IOqtaneDatabase database) : base(database)
{
}

View File

@ -11,7 +11,7 @@ namespace Oqtane.Migrations
[Migration("Tenant.02.00.02.02")]
public class UpdateDefaultContainerTypeInSitePage : MultiDatabaseMigration
{
public UpdateDefaultContainerTypeInSitePage(IEnumerable<IOqtaneDatabase> databases) : base(databases)
public UpdateDefaultContainerTypeInSitePage(IOqtaneDatabase database) : base(database)
{
}

View File

@ -11,7 +11,7 @@ namespace Oqtane.Migrations
[Migration("Tenant.02.00.02.03")]
public class DropDefaultLayoutInSite : MultiDatabaseMigration
{
public DropDefaultLayoutInSite(IEnumerable<IOqtaneDatabase> databases) : base(databases)
public DropDefaultLayoutInSite(IOqtaneDatabase database) : base(database)
{
}

View File

@ -12,7 +12,7 @@ namespace Oqtane.Migrations
[Migration("Tenant.02.01.00.00")]
public class AddAppVersionsTable : MultiDatabaseMigration
{
public AddAppVersionsTable(IEnumerable<IOqtaneDatabase> databases) : base(databases)
public AddAppVersionsTable(IOqtaneDatabase database) : base(database)
{
}

View File

@ -11,7 +11,7 @@ namespace Oqtane.Migrations
[Migration("Master.02.01.00.00")]
public class AddIndexesForForeignKeyInMaster : MultiDatabaseMigration
{
public AddIndexesForForeignKeyInMaster(IEnumerable<IOqtaneDatabase> databases) : base(databases)
public AddIndexesForForeignKeyInMaster(IOqtaneDatabase database) : base(database)
{
}

View File

@ -11,7 +11,7 @@ namespace Oqtane.Migrations
[Migration("Master.02.01.00.01")]
public class AddDatabaseTypeColumnToTenant : MultiDatabaseMigration
{
public AddDatabaseTypeColumnToTenant(IEnumerable<IOqtaneDatabase> databases) : base(databases)
public AddDatabaseTypeColumnToTenant(IOqtaneDatabase database) : base(database)
{
}

View File

@ -7,14 +7,14 @@ namespace Oqtane.Migrations
{
public abstract class MultiDatabaseMigration : Migration
{
private readonly IEnumerable<IOqtaneDatabase> _databases;
private readonly IOqtaneDatabase _databases;
protected MultiDatabaseMigration(IEnumerable<IOqtaneDatabase> 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)
{

View File

@ -13,7 +13,7 @@ namespace Oqtane.Migrations.Framework
{
public class MultiDatabaseMigrationsAssembly: MigrationsAssembly
{
private readonly IEnumerable<IOqtaneDatabase> _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<IOqtaneDatabase>) }) != 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;

View File

@ -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<IOqtaneDatabase> _databases;
private readonly ITenantManager _tenantManager;
private readonly IHttpContextAccessor _accessor;
public HtmlTextManager(IHtmlTextRepository htmlText, IEnumerable<IOqtaneDatabase> 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);
}
}
}

View File

@ -12,7 +12,7 @@ namespace Oqtane.Modules.HtmlText.Migrations
[Migration("HtmlText.01.00.00.00")]
public class InitializeModule : MultiDatabaseMigration
{
public InitializeModule(IEnumerable<IOqtaneDatabase> databases) : base(databases)
public InitializeModule(IOqtaneDatabase database) : base(database)
{
}

View File

@ -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<Models.HtmlText> HtmlText { get; set; }
}

View File

@ -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<IOqtaneDatabase> 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);
var type = Type.GetType(_databaseType);
ActiveDatabase = Activator.CreateInstance(type) as IOqtaneDatabase;
}
else
if (!string.IsNullOrEmpty(_connectionString) && ActiveDatabase != null)
{
optionsBuilder.UseOqtaneDatabase(_databaseType, _connectionString);
}
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;
}
}
}

View File

@ -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<IOqtaneDatabase> databases)
{
Accessor = accessor;
Configuration = configuration;
Databases = databases;
}
public IHttpContextAccessor Accessor { get; }
public IConfiguration Configuration { get; }
public IEnumerable<IOqtaneDatabase> Databases { get; set; }
public string ConnectionString { get; set; }
public string DatabaseType { get; set; }
}
}

View File

@ -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<MasterDBContext> options, IDbConfig dbConfig) : base(options)
public MasterDBContext(DbContextOptions<MasterDBContext> options, IHttpContextAccessor accessor, IConfiguration configuration) : base(options)
{
_dbConfig = dbConfig;
Databases = dbConfig.Databases;
_accessor = accessor;
_configuration = configuration;
}
public IEnumerable<IOqtaneDatabase> Databases { get; }
public IOqtaneDatabase ActiveDatabase { get; private set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.ReplaceService<IMigrationsAssembly, MultiDatabaseMigrationsAssembly>();
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);
var type = Type.GetType(_databaseType);
ActiveDatabase = Activator.CreateInstance(type) as IOqtaneDatabase;
}
else
if (!string.IsNullOrEmpty(_connectionString) && ActiveDatabase != null)
{
optionsBuilder.UseOqtaneDatabase(databaseType, connectionString);
}
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();
}

View File

@ -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> Site { get; set; }
public virtual DbSet<Page> Page { get; set; }

View File

@ -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<IOqtaneDatabase> Databases { get; set; }
public string ConnectionString { get; set; }
public string DatabaseType { get; set; }
}
}

View File

@ -14,13 +14,6 @@ namespace Oqtane.Repository
{
public class SqlRepository : ISqlRepository
{
private IEnumerable<IOqtaneDatabase> _databases;
public SqlRepository(IEnumerable<IOqtaneDatabase> 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;
}
}
}

View File

@ -210,7 +210,6 @@ namespace Oqtane
// load the external assemblies into the app domain, install services
services.AddOqtane(_runtime, _supportedCultures);
services.AddScoped<IDbConfig, DbConfig>();
services.AddDbContext<MasterDBContext>(options => { });
services.AddDbContext<TenantDBContext>(options => { });

View File

@ -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; }