diff --git a/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/EntityFrameworkWebhookStartupBase.cs b/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/EntityFrameworkWebhookStartupBase.cs index af5e3f21c..d5aa71dd8 100644 --- a/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/EntityFrameworkWebhookStartupBase.cs +++ b/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/EntityFrameworkWebhookStartupBase.cs @@ -16,7 +16,7 @@ namespace Elsa.Webhooks.Persistence.EntityFramework.Core public override void ConfigureElsa(ElsaOptionsBuilder elsa, IConfiguration configuration) { var services = elsa.Services; - var section = configuration.GetSection($"Elsa:Persistence:{ProviderName}"); + var section = configuration.GetSection($"Elsa:Features:Webhooks:Persistence:EntityFrameworkCore:{ProviderName}"); var connectionStringName = section.GetValue("ConnectionStringName"); var connectionString = section.GetValue("ConnectionString"); diff --git a/src/activities/webhooks/Elsa.Webhooks.Persistence.MongoDb/Startup.cs b/src/activities/webhooks/Elsa.Webhooks.Persistence.MongoDb/Startup.cs index c8295b9dd..98a249f44 100644 --- a/src/activities/webhooks/Elsa.Webhooks.Persistence.MongoDb/Startup.cs +++ b/src/activities/webhooks/Elsa.Webhooks.Persistence.MongoDb/Startup.cs @@ -1,7 +1,6 @@ using Elsa.Activities.Webhooks; using Elsa.Activities.Webhooks.Persistence.Decorators; using Elsa.Attributes; -using Elsa.Persistence.MongoDb.Options; using Elsa.Services.Startup; using Elsa.Webhooks.Persistence.MongoDb.Extensions; using Microsoft.Extensions.Configuration; @@ -15,7 +14,7 @@ namespace Elsa.Webhooks.Persistence.MongoDb public override void ConfigureElsa(ElsaOptionsBuilder elsa, IConfiguration configuration) { var services = elsa.Services; - var section = configuration.GetSection($"Elsa:Persistence:MongoDb"); + var section = configuration.GetSection($"Elsa:Features:Webhooks:Persistence:MongoDb"); var connectionStringName = section.GetValue("ConnectionStringName"); var connectionString = section.GetValue("ConnectionString"); diff --git a/src/activities/webhooks/Elsa.Webhooks.Persistence.YesSql/Startups.cs b/src/activities/webhooks/Elsa.Webhooks.Persistence.YesSql/Startups.cs index 51081f3cf..b605ee7bb 100644 --- a/src/activities/webhooks/Elsa.Webhooks.Persistence.YesSql/Startups.cs +++ b/src/activities/webhooks/Elsa.Webhooks.Persistence.YesSql/Startups.cs @@ -49,7 +49,7 @@ namespace Elsa.Webhooks.Persistence.YesSql public override void ConfigureElsa(ElsaOptionsBuilder elsa, IConfiguration configuration) { var services = elsa.Services; - var section = configuration.GetSection($"Elsa:Persistence:{ProviderName}"); + var section = configuration.GetSection($"Elsa:Features:Webhooks:Persistence:YesSql:{ProviderName}"); var connectionStringName = section.GetValue("ConnectionStringName"); var connectionString = section.GetValue("ConnectionString"); diff --git a/src/core/Elsa.Core/ElsaOptions.cs b/src/core/Elsa.Core/ElsaOptions.cs index e0bd103ac..c80107e2e 100644 --- a/src/core/Elsa.Core/ElsaOptions.cs +++ b/src/core/Elsa.Core/ElsaOptions.cs @@ -77,6 +77,7 @@ namespace Elsa public Type DefaultWorkflowStorageProviderType { get; set; } public WorkflowChannelOptions WorkflowChannelOptions { get; set; } = new(); + public FeatureOptions FeatureOptions { get; set; } = new(); internal Func StorageFactory { get; set; } internal Func WorkflowDefinitionStoreFactory { get; set; } diff --git a/src/core/Elsa.Core/ElsaOptionsBuilder.cs b/src/core/Elsa.Core/ElsaOptionsBuilder.cs index 9b5261b8a..ad2c9d53d 100644 --- a/src/core/Elsa.Core/ElsaOptionsBuilder.cs +++ b/src/core/Elsa.Core/ElsaOptionsBuilder.cs @@ -8,6 +8,7 @@ using Elsa.Persistence; using Elsa.Providers.WorkflowStorage; using Elsa.Services; using Elsa.Services.Messaging; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; using Rebus.DataBus.InMem; @@ -64,6 +65,26 @@ namespace Elsa return this; } + public ElsaOptionsBuilder ConfigureFeatures(IConfigurationSection configuration) + { + ElsaOptions.FeatureOptions.Features = new Dictionary(); + var features = configuration.AsEnumerable(); + + foreach (var feature in features) + { + if (feature.Key.EndsWith(":ConnectionStringName")) continue; + + if (feature.Value != null && bool.Parse(feature.Value)) + { + ElsaOptions.FeatureOptions.Features.Add(feature.Key + .Replace("Elsa:Features:", string.Empty) + .Replace(":Enabled", string.Empty), true); + } + } + + return this; + } + public ElsaOptionsBuilder AddActivity() where T : IActivity => AddActivity(typeof(T)); public ElsaOptionsBuilder AddActivity(Type activityType) diff --git a/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs b/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs index 3661d3476..7be9c0eab 100644 --- a/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs +++ b/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs @@ -10,17 +10,18 @@ namespace Elsa { public static class ElsaOptionBuilderExtensions { - public static ElsaOptionsBuilder AddFeatures(this ElsaOptionsBuilder builder, IEnumerable assemblyMarkerTypes, IConfiguration configuration, IEnumerable features) => AddFeatures(builder, GetAssemblies(assemblyMarkerTypes), configuration, features); + public static ElsaOptionsBuilder AddFeatures(this ElsaOptionsBuilder builder, IEnumerable assemblyMarkerTypes, IConfiguration configuration) => AddFeatures(builder, GetAssemblies(assemblyMarkerTypes), configuration); - public static ElsaOptionsBuilder AddFeatures(this ElsaOptionsBuilder builder, IEnumerable assemblies, IConfiguration configuration, IEnumerable features) + public static ElsaOptionsBuilder AddFeatures(this ElsaOptionsBuilder builder, IEnumerable assemblies, IConfiguration configuration) { - var enabledFeatures = features.ToHashSet(); + var enabledFeatures = builder.ElsaOptions.FeatureOptions.Features.ToHashSet(); var startupTypesQuery = from assembly in assemblies from type in assembly.GetExportedTypes() where type.IsClass && !type.IsAbstract && typeof(IStartup).IsAssignableFrom(type) let featureAttribute = type.GetCustomAttribute() - where featureAttribute != null && enabledFeatures.Contains(featureAttribute.FeatureName) + let enabledFeature = enabledFeatures.FirstOrDefault(x => x.Key == featureAttribute.FeatureName && x.Value) + where featureAttribute != null && !enabledFeature.Equals(default(KeyValuePair)) select type; var startupTypes = startupTypesQuery.ToList(); diff --git a/src/core/Elsa.Core/FeatureOptions.cs b/src/core/Elsa.Core/FeatureOptions.cs new file mode 100644 index 000000000..1eb301cca --- /dev/null +++ b/src/core/Elsa.Core/FeatureOptions.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace Elsa +{ + public class FeatureOptions + { + public Dictionary? Features { get; set; } + } +} diff --git a/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/EntityFrameworkCoreStartupBase.cs b/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/EntityFrameworkCoreStartupBase.cs index 25026ca10..6cf381516 100644 --- a/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/EntityFrameworkCoreStartupBase.cs +++ b/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/EntityFrameworkCoreStartupBase.cs @@ -12,7 +12,7 @@ namespace Elsa.Persistence.EntityFramework.Core public override void ConfigureElsa(ElsaOptionsBuilder elsa, IConfiguration configuration) { - var section = configuration.GetSection($"Elsa:Persistence:{ProviderName}"); + var section = configuration.GetSection($"Elsa:Features:Persistence:EntityFrameworkCore:{ProviderName}"); var connectionStringName = section.GetValue("ConnectionStringName"); var connectionString = section.GetValue("ConnectionString"); diff --git a/src/persistence/Elsa.Persistence.MongoDb/Startup.cs b/src/persistence/Elsa.Persistence.MongoDb/Startup.cs index 20c55c9c5..38eaf73ca 100644 --- a/src/persistence/Elsa.Persistence.MongoDb/Startup.cs +++ b/src/persistence/Elsa.Persistence.MongoDb/Startup.cs @@ -9,7 +9,7 @@ namespace Elsa.Persistence.MongoDb { public override void ConfigureElsa(ElsaOptionsBuilder elsa, IConfiguration configuration) { - var section = configuration.GetSection($"Elsa:Persistence:MongoDb"); + var section = configuration.GetSection($"Elsa:Features:Persistence:MongoDb"); var connectionStringName = section.GetValue("ConnectionStringName"); var connectionString = section.GetValue("ConnectionString"); diff --git a/src/persistence/Elsa.Persistence.YesSql/Startups.cs b/src/persistence/Elsa.Persistence.YesSql/Startups.cs index c1d608981..ffcce94d6 100644 --- a/src/persistence/Elsa.Persistence.YesSql/Startups.cs +++ b/src/persistence/Elsa.Persistence.YesSql/Startups.cs @@ -44,7 +44,7 @@ namespace Elsa.Persistence.YesSql public override void ConfigureElsa(ElsaOptionsBuilder elsa, IConfiguration configuration) { - var section = configuration.GetSection($"Elsa:Persistence:{ProviderName}"); + var section = configuration.GetSection($"Elsa:Features:Persistence:YesSql:{ProviderName}"); var connectionStringName = section.GetValue("ConnectionStringName"); var connectionString = section.GetValue("ConnectionString"); diff --git a/src/samples/server/Elsa.Samples.Server.Host/Startup.cs b/src/samples/server/Elsa.Samples.Server.Host/Startup.cs index 4178a5ff0..25bf66065 100644 --- a/src/samples/server/Elsa.Samples.Server.Host/Startup.cs +++ b/src/samples/server/Elsa.Samples.Server.Host/Startup.cs @@ -1,5 +1,3 @@ -using System.Collections.Generic; -using Elsa.Samples.Server.Host.Activities; using Elsa.Server.Hangfire.Extensions; using Hangfire; using Microsoft.AspNetCore.Builder; @@ -7,6 +5,8 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using System.Collections.Generic; +using System.Linq; namespace Elsa.Samples.Server.Host { @@ -67,7 +67,8 @@ namespace Elsa.Samples.Server.Host .AddElsa(elsa => elsa .AddActivitiesFrom() .AddWorkflowsFrom() - .AddFeatures(startups, Configuration, elsaSection.GetSection("Features").Get>()) + .ConfigureFeatures(elsaSection.GetSection("Features")) + .AddFeatures(startups, Configuration) .ConfigureWorkflowChannels(options => elsaSection.GetSection("WorkflowChannels").Bind(options)) ); diff --git a/src/samples/server/Elsa.Samples.Server.Host/appsettings.json b/src/samples/server/Elsa.Samples.Server.Host/appsettings.json index 4a9984de6..de5793da5 100644 --- a/src/samples/server/Elsa.Samples.Server.Host/appsettings.json +++ b/src/samples/server/Elsa.Samples.Server.Host/appsettings.json @@ -18,34 +18,45 @@ "PostgreSql": "Server=127.0.0.1;Port=5432;Database=elsa;User Id=postgres;Password=password;" }, "Elsa": { - "Features": [ - "Persistence:EntityFrameworkCore:Sqlite", - "Dispatcher:Hangfire", - "Console", - "Http", - "Email", - "Temporal:Quartz", - "JavaScript:Activities", - "UserTask", - "Conductor", - "Telnyx", - "Webhooks", - "Webhooks:Persistence:EntityFrameworkCore:Sqlite" - ], - "Persistence:MySql": { - "ConnectionStringName": "MySql" - }, - "Persistence:SqlServer": { - "ConnectionStringName": "SqlServer" - }, - "Persistence:Sqlite": { - "ConnectionStringName": "Sqlite" - }, - "Persistence:MongoDb": { - "ConnectionStringName": "MongoDb" - }, - "Persistence:PostgreSql": { - "ConnectionStringName": "PostgreSql" + "Features": { + "Persistence:EntityFrameworkCore:Sqlite": { + "Enabled": "true", + "ConnectionStringName": "Sqlite" + }, + "Dispatcher:Hangfire": { + "Enabled": "true" + }, + "Console": { + "Enabled": "true" + }, + "Http": { + "Enabled": "true" + }, + "Email": { + "Enabled": "true" + }, + "Temporal:Quartz": { + "Enabled": "true" + }, + "JavaScript:Activities": { + "Enabled": "true" + }, + "UserTask": { + "Enabled": "true" + }, + "Conductor": { + "Enabled": "true" + }, + "Telnyx": { + "Enabled": "true" + }, + "Webhooks": { + "Enabled": "true" + }, + "Webhooks:Persistence:EntityFrameworkCore:Sqlite": { + "Enabled": "true", + "ConnectionStringName": "Sqlite" + } }, "WorkflowChannels": { "Channels": [