From 103034667cecb4dcf851c7fcd8a3719a5ed45181 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Mon, 11 Nov 2024 19:01:41 +0100 Subject: [PATCH] Add configuration actions for DbContext options builders (#6110) * Add configuration actions for DbContext options builders Introduce a configuration delegate parameter for each database provider's `Use*` methods, enhancing customization. This change affects MySql, SqlServer, Sqlite, PostgreSql, and Oracle providers, allowing more flexible DbContext configuration. * Add support for connection strings as functions This update introduces new overloads to allow passing connection strings as functions that take IServiceProvider. This enhances flexibility by enabling dynamic connection string resolution at runtime. All major database providers (MySQL, SQL Server, SQLite, PostgreSQL, and Oracle) have been updated accordingly. --- .../MySqlProvidersExtensions.cs | 40 +++++++++- .../Features.cs | 80 ------------------- .../OracleProvidersExtensions.cs | 59 ++++++++++++++ .../PostgreSqlProvidersExtensions.cs | 41 ++++++++-- .../SqlServerProvidersExtensions.cs | 37 ++++++++- .../SqliteProvidersExtensions.cs | 31 +++++-- 6 files changed, 186 insertions(+), 102 deletions(-) delete mode 100644 src/modules/Elsa.EntityFrameworkCore.Oracle/Features.cs create mode 100644 src/modules/Elsa.EntityFrameworkCore.Oracle/OracleProvidersExtensions.cs diff --git a/src/modules/Elsa.EntityFrameworkCore.MySql/MySqlProvidersExtensions.cs b/src/modules/Elsa.EntityFrameworkCore.MySql/MySqlProvidersExtensions.cs index faf842aff..09ee321e2 100644 --- a/src/modules/Elsa.EntityFrameworkCore.MySql/MySqlProvidersExtensions.cs +++ b/src/modules/Elsa.EntityFrameworkCore.MySql/MySqlProvidersExtensions.cs @@ -1,4 +1,5 @@ using System.Reflection; +using Microsoft.EntityFrameworkCore.Infrastructure; // ReSharper disable once CheckNamespace namespace Elsa.EntityFrameworkCore.Extensions; @@ -10,18 +11,49 @@ public static class MySqlProvidersExtensions { private static Assembly Assembly => typeof(MySqlProvidersExtensions).Assembly; - public static TFeature UseMySql(this PersistenceFeatureBase feature, string connectionString, ElsaDbContextOptions? options = null) + public static TFeature UseMySql(this PersistenceFeatureBase feature, + string connectionString, + ElsaDbContextOptions? options = null, + Action? configure = null) where TDbContext : ElsaDbContextBase where TFeature : PersistenceFeatureBase { - return feature.UseMySql(Assembly, connectionString, options); + return feature.UseMySql(Assembly, connectionString, options, configure); } - public static TFeature UseMySql(this PersistenceFeatureBase feature, Assembly migrationsAssembly, string connectionString, ElsaDbContextOptions? options = null) + public static TFeature UseMySql(this PersistenceFeatureBase feature, + Func connectionStringFunc, + ElsaDbContextOptions? options = null, + Action? configure = null + ) where TDbContext : ElsaDbContextBase where TFeature : PersistenceFeatureBase { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaMySql(Assembly, connectionString, options); + return feature.UseMySql(Assembly, connectionStringFunc, options, configure); + } + + public static TFeature UseMySql(this PersistenceFeatureBase feature, + Assembly migrationsAssembly, + string connectionString, + ElsaDbContextOptions? options = null, + Action? configure = null + ) + where TDbContext : ElsaDbContextBase + where TFeature : PersistenceFeatureBase + { + return feature.UseMySql(migrationsAssembly, _ => connectionString, options, configure); + } + + public static TFeature UseMySql(this PersistenceFeatureBase feature, + Assembly migrationsAssembly, + Func connectionStringFunc, + ElsaDbContextOptions? options = null, + Action? configure = null + ) + where TDbContext : ElsaDbContextBase + where TFeature : PersistenceFeatureBase + { + feature.DbContextOptionsBuilder = (sp, db) => db.UseElsaMySql(migrationsAssembly, connectionStringFunc(sp), options, configure: configure); return (TFeature)feature; } } \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore.Oracle/Features.cs b/src/modules/Elsa.EntityFrameworkCore.Oracle/Features.cs deleted file mode 100644 index a530cb1fd..000000000 --- a/src/modules/Elsa.EntityFrameworkCore.Oracle/Features.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System.Reflection; -using Elsa.EntityFrameworkCore.Modules.Alterations; -using Elsa.EntityFrameworkCore.Modules.Identity; -using Elsa.EntityFrameworkCore.Modules.Labels; -using Elsa.EntityFrameworkCore.Modules.Management; -using Elsa.EntityFrameworkCore.Modules.Runtime; - -// ReSharper disable once CheckNamespace -namespace Elsa.EntityFrameworkCore.Extensions; - -/// -/// Provides extensions to configure EF Core to use Oracle. -/// -public static class OracleProvidersExtensions -{ - private static Assembly Assembly => typeof(OracleProvidersExtensions).Assembly; - - /// - /// Configures the to use Oracle. - /// - public static EFCoreIdentityPersistenceFeature UseOracle(this EFCoreIdentityPersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) - { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaOracle(Assembly, connectionString, options); - return feature; - } - - /// - /// Configures the to use Oracle. - /// - public static EFCoreAlterationsPersistenceFeature UseOracle(this EFCoreAlterationsPersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) - { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaOracle(Assembly, connectionString, options); - return feature; - } - - /// - /// Configures the to use Oracle. - /// - public static EFCoreLabelPersistenceFeature UseOracle(this EFCoreLabelPersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) - { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaOracle(Assembly, connectionString, options); - return feature; - } - - /// - /// Configures the to use Oracle. - /// - public static EFCoreWorkflowDefinitionPersistenceFeature UseOracle(this EFCoreWorkflowDefinitionPersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) - { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaOracle(Assembly, connectionString, options); - return feature; - } - - /// - /// Configures the to use Oracle. - /// - public static EFCoreWorkflowInstancePersistenceFeature UseOracle(this EFCoreWorkflowInstancePersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) - { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaOracle(Assembly, connectionString, options); - return feature; - } - - /// - /// Configures the to use Oracle. - /// - public static WorkflowManagementPersistenceFeature UseOracle(this WorkflowManagementPersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) - { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaOracle(Assembly, connectionString, options); - return feature; - } - - /// - /// Configures the to use Oracle. - /// - public static EFCoreWorkflowRuntimePersistenceFeature UseOracle(this EFCoreWorkflowRuntimePersistenceFeature feature, string connectionString, ElsaDbContextOptions? options = default) - { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaOracle(Assembly, connectionString, options); - return feature; - } -} \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore.Oracle/OracleProvidersExtensions.cs b/src/modules/Elsa.EntityFrameworkCore.Oracle/OracleProvidersExtensions.cs new file mode 100644 index 000000000..040c82912 --- /dev/null +++ b/src/modules/Elsa.EntityFrameworkCore.Oracle/OracleProvidersExtensions.cs @@ -0,0 +1,59 @@ +using System.Reflection; +using Oracle.EntityFrameworkCore.Infrastructure; + +// ReSharper disable once CheckNamespace +namespace Elsa.EntityFrameworkCore.Extensions; + +/// +/// Provides extensions to configure EF Core to use Oracle. +/// +public static class OracleProvidersExtensions +{ + private static Assembly Assembly => typeof(OracleProvidersExtensions).Assembly; + + public static TFeature UseMySql(this PersistenceFeatureBase feature, + string connectionString, + ElsaDbContextOptions? options = null, + Action? configure = null) + where TDbContext : ElsaDbContextBase + where TFeature : PersistenceFeatureBase + { + return feature.UseMySql(Assembly, connectionString, options, configure); + } + + public static TFeature UseMySql(this PersistenceFeatureBase feature, + Func connectionStringFunc, + ElsaDbContextOptions? options = null, + Action? configure = null + ) + where TDbContext : ElsaDbContextBase + where TFeature : PersistenceFeatureBase + { + return feature.UseMySql(Assembly, connectionStringFunc, options, configure); + } + + public static TFeature UseMySql(this PersistenceFeatureBase feature, + Assembly migrationsAssembly, + string connectionString, + ElsaDbContextOptions? options = null, + Action? configure = null + ) + where TDbContext : ElsaDbContextBase + where TFeature : PersistenceFeatureBase + { + return feature.UseMySql(migrationsAssembly, _ => connectionString, options, configure); + } + + public static TFeature UseMySql(this PersistenceFeatureBase feature, + Assembly migrationsAssembly, + Func connectionStringFunc, + ElsaDbContextOptions? options = null, + Action? configure = null + ) + where TDbContext : ElsaDbContextBase + where TFeature : PersistenceFeatureBase + { + feature.DbContextOptionsBuilder = (sp, db) => db.UseElsaOracle(migrationsAssembly, connectionStringFunc(sp), options, configure: configure); + return (TFeature)feature; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore.PostgreSql/PostgreSqlProvidersExtensions.cs b/src/modules/Elsa.EntityFrameworkCore.PostgreSql/PostgreSqlProvidersExtensions.cs index 115608264..713860fd0 100644 --- a/src/modules/Elsa.EntityFrameworkCore.PostgreSql/PostgreSqlProvidersExtensions.cs +++ b/src/modules/Elsa.EntityFrameworkCore.PostgreSql/PostgreSqlProvidersExtensions.cs @@ -1,4 +1,5 @@ using System.Reflection; +using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure; // ReSharper disable once CheckNamespace namespace Elsa.EntityFrameworkCore.Extensions; @@ -9,19 +10,47 @@ namespace Elsa.EntityFrameworkCore.Extensions; public static class PostgreSqlProvidersExtensions { private static Assembly Assembly => typeof(PostgreSqlProvidersExtensions).Assembly; - - public static TFeature UsePostgreSql(this PersistenceFeatureBase feature, string connectionString, ElsaDbContextOptions? options = null) + + public static TFeature UsePostgreSql(this PersistenceFeatureBase feature, + string connectionString, + ElsaDbContextOptions? options = null, + Action? configure = null) where TDbContext : ElsaDbContextBase where TFeature : PersistenceFeatureBase { - return feature.UsePostgreSql(Assembly, connectionString, options); + return feature.UsePostgreSql(Assembly, connectionString, options, configure); } - - public static TFeature UsePostgreSql(this PersistenceFeatureBase feature, Assembly migrationsAssembly, string connectionString, ElsaDbContextOptions? options = null) + + public static TFeature UsePostgreSql(this PersistenceFeatureBase feature, + Func connectionStringFunc, + ElsaDbContextOptions? options = null, + Action? configure = null) where TDbContext : ElsaDbContextBase where TFeature : PersistenceFeatureBase { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaPostgreSql(migrationsAssembly, connectionString, options); + return feature.UsePostgreSql(Assembly, connectionStringFunc, options, configure); + } + + public static TFeature UsePostgreSql(this PersistenceFeatureBase feature, + Assembly migrationsAssembly, + string connectionString, + ElsaDbContextOptions? options = null, + Action? configure = null) + where TDbContext : ElsaDbContextBase + where TFeature : PersistenceFeatureBase + { + return feature.UsePostgreSql(migrationsAssembly, _ => connectionString, options, configure); + } + + public static TFeature UsePostgreSql(this PersistenceFeatureBase feature, + Assembly migrationsAssembly, + Func connectionStringFunc, + ElsaDbContextOptions? options = null, + Action? configure = null) + where TDbContext : ElsaDbContextBase + where TFeature : PersistenceFeatureBase + { + feature.DbContextOptionsBuilder = (sp, db) => db.UseElsaPostgreSql(migrationsAssembly, connectionStringFunc(sp), options, configure: configure); return (TFeature)feature; } } \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore.SqlServer/SqlServerProvidersExtensions.cs b/src/modules/Elsa.EntityFrameworkCore.SqlServer/SqlServerProvidersExtensions.cs index 0abe3e1e0..32b18e139 100644 --- a/src/modules/Elsa.EntityFrameworkCore.SqlServer/SqlServerProvidersExtensions.cs +++ b/src/modules/Elsa.EntityFrameworkCore.SqlServer/SqlServerProvidersExtensions.cs @@ -1,4 +1,5 @@ using System.Reflection; +using Microsoft.EntityFrameworkCore.Infrastructure; // ReSharper disable once CheckNamespace namespace Elsa.EntityFrameworkCore.Extensions; @@ -10,18 +11,46 @@ public static class SqlServerProvidersExtensions { private static Assembly Assembly => typeof(SqlServerProvidersExtensions).Assembly; - public static TFeature UseSqlServer(this PersistenceFeatureBase feature, string connectionString, ElsaDbContextOptions? options = null) + public static TFeature UseSqlServer(this PersistenceFeatureBase feature, + string connectionString, + ElsaDbContextOptions? options = null, + Action? configure = null) where TDbContext : ElsaDbContextBase where TFeature : PersistenceFeatureBase { - return feature.UseSqlServer(Assembly, connectionString, options); + return feature.UseSqlServer(Assembly, connectionString, options, configure); } - public static TFeature UseSqlServer(this PersistenceFeatureBase feature, Assembly migrationsAssembly, string connectionString, ElsaDbContextOptions? options = null) + public static TFeature UseSqlServer(this PersistenceFeatureBase feature, + Func connectionStringFunc, + ElsaDbContextOptions? options = null, + Action? configure = null) where TDbContext : ElsaDbContextBase where TFeature : PersistenceFeatureBase { - feature.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlServer(migrationsAssembly, connectionString, options); + return feature.UseSqlServer(Assembly, connectionStringFunc, options, configure); + } + + public static TFeature UseSqlServer(this PersistenceFeatureBase feature, + Assembly migrationsAssembly, + string connectionString, + ElsaDbContextOptions? options = null, + Action? configure = null) + where TDbContext : ElsaDbContextBase + where TFeature : PersistenceFeatureBase + { + return feature.UseSqlServer(migrationsAssembly, _ => connectionString, options, configure); + } + + public static TFeature UseSqlServer(this PersistenceFeatureBase feature, + Assembly migrationsAssembly, + Func connectionStringFunc, + ElsaDbContextOptions? options = null, + Action? configure = null) + where TDbContext : ElsaDbContextBase + where TFeature : PersistenceFeatureBase + { + feature.DbContextOptionsBuilder = (sp, db) => db.UseElsaSqlServer(migrationsAssembly, connectionStringFunc(sp), options, configure); return (TFeature)feature; } } \ No newline at end of file diff --git a/src/modules/Elsa.EntityFrameworkCore.Sqlite/SqliteProvidersExtensions.cs b/src/modules/Elsa.EntityFrameworkCore.Sqlite/SqliteProvidersExtensions.cs index 31dc0c3a3..635abfac5 100644 --- a/src/modules/Elsa.EntityFrameworkCore.Sqlite/SqliteProvidersExtensions.cs +++ b/src/modules/Elsa.EntityFrameworkCore.Sqlite/SqliteProvidersExtensions.cs @@ -1,5 +1,6 @@ using System.Reflection; using Elsa.EntityFrameworkCore.EntityHandlers; +using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.Extensions.DependencyInjection; // ReSharper disable once CheckNamespace @@ -15,43 +16,57 @@ public static class SqliteProvidersExtensions /// /// Configures the feature to use Sqlite. /// - public static TFeature UseSqlite(this PersistenceFeatureBase feature, string? connectionString = null, ElsaDbContextOptions? options = null) + public static TFeature UseSqlite(this PersistenceFeatureBase feature, + string? connectionString = null, + ElsaDbContextOptions? options = null, + Action? configure = null) where TDbContext : ElsaDbContextBase where TFeature : PersistenceFeatureBase { - return feature.UseSqlite(Assembly, connectionString, options); + return feature.UseSqlite(Assembly, connectionString, options, configure); } /// /// Configures the feature to use Sqlite. /// - public static TFeature UseSqlite(this PersistenceFeatureBase feature, Func connectionStringFunc, ElsaDbContextOptions? options = null) + public static TFeature UseSqlite(this PersistenceFeatureBase feature, + Func connectionStringFunc, + ElsaDbContextOptions? options = null, + Action? configure = null) where TDbContext : ElsaDbContextBase where TFeature : PersistenceFeatureBase { - return feature.UseSqlite(Assembly, connectionStringFunc, options); + return feature.UseSqlite(Assembly, connectionStringFunc, options, configure); } /// /// Configures the feature to use Sqlite. /// - public static TFeature UseSqlite(this PersistenceFeatureBase feature, Assembly migrationsAssembly, string? connectionString = null, ElsaDbContextOptions? options = null) + public static TFeature UseSqlite(this PersistenceFeatureBase feature, + Assembly migrationsAssembly, + string? connectionString = null, + ElsaDbContextOptions? options = null, + Action? configure = null) where TDbContext : ElsaDbContextBase where TFeature : PersistenceFeatureBase { connectionString ??= "Data Source=elsa.sqlite.db;Cache=Shared;"; - return feature.UseSqlite(migrationsAssembly, _ => connectionString, options); + return feature.UseSqlite(migrationsAssembly, _ => connectionString, options, configure); } /// /// Configures the feature to use Sqlite. /// - public static TFeature UseSqlite(this PersistenceFeatureBase feature, Assembly migrationsAssembly, Func connectionStringFunc, ElsaDbContextOptions? options = null) + public static TFeature UseSqlite(this PersistenceFeatureBase feature, + Assembly migrationsAssembly, + Func connectionStringFunc, + ElsaDbContextOptions? options = null, + Action? configure = null) where TDbContext : ElsaDbContextBase where TFeature : PersistenceFeatureBase { feature.Module.Services.AddScoped(); - feature.DbContextOptionsBuilder = (sp, db) => db.UseElsaSqlite(migrationsAssembly, connectionStringFunc(sp), options); + feature.DbContextOptionsBuilder = (sp, db) => db.UseElsaSqlite(migrationsAssembly, connectionStringFunc(sp), options, configure: configure); return (TFeature)feature; } } \ No newline at end of file