Code and appsettings optimisation for Features

Code and appsettings optimisation for Features
This commit is contained in:
axeleron007 2021-07-06 16:21:53 +03:00
parent f23227a0e7
commit df5d380a33
14 changed files with 61 additions and 109 deletions

View file

@ -17,8 +17,8 @@ namespace Elsa.Webhooks.Persistence.EntityFramework.Core
{
var services = elsa.Services;
var section = configuration.GetSection($"Elsa:Features:Webhooks:Persistence:EntityFrameworkCore:{ProviderName}");
var connectionStringName = section.GetValue<string>("Options:ConnectionStringName");
var connectionString = section.GetValue<string>("Options:ConnectionString");
var connectionStringName = section.GetValue<string>("ConnectionStringName");
var connectionString = section.GetValue<string>("ConnectionString");
if (string.IsNullOrWhiteSpace(connectionString))
{

View file

@ -15,8 +15,8 @@ namespace Elsa.Webhooks.Persistence.MongoDb
{
var services = elsa.Services;
var section = configuration.GetSection($"Elsa:Features:Webhooks:Persistence:MongoDb");
var connectionStringName = section.GetValue<string>("Options:ConnectionStringName");
var connectionString = section.GetValue<string>("Options:ConnectionString");
var connectionStringName = section.GetValue<string>("ConnectionStringName");
var connectionString = section.GetValue<string>("ConnectionString");
if (string.IsNullOrWhiteSpace(connectionString))
{

View file

@ -50,8 +50,8 @@ namespace Elsa.Webhooks.Persistence.YesSql
{
var services = elsa.Services;
var section = configuration.GetSection($"Elsa:Features:Webhooks:Persistence:YesSql:{ProviderName}");
var connectionStringName = section.GetValue<string>("Options:ConnectionStringName");
var connectionString = section.GetValue<string>("Options:ConnectionString");
var connectionStringName = section.GetValue<string>("ConnectionStringName");
var connectionString = section.GetValue<string>("ConnectionString");
if (string.IsNullOrWhiteSpace(connectionString))
{

View file

@ -77,7 +77,6 @@ namespace Elsa
public Type DefaultWorkflowStorageProviderType { get; set; }
public WorkflowChannelOptions WorkflowChannelOptions { get; set; } = new();
public FeatureOptions FeatureOptions { get; set; } = new();
internal Func<IServiceProvider, IBlobStorage> StorageFactory { get; set; }
internal Func<IServiceProvider, IWorkflowDefinitionStore> WorkflowDefinitionStoreFactory { get; set; }

View file

@ -66,38 +66,6 @@ namespace Elsa
return this;
}
public ElsaOptionsBuilder ConfigureFeatures(IConfiguration configuration)
{
var elsaFeaturesSection = "Elsa:Features";
ElsaOptions.FeatureOptions.Features = new List<FeatureOption>();
var features = configuration.GetSection(elsaFeaturesSection).AsEnumerable();
foreach (var feature in features)
{
if (!configuration.GetSection($"{feature.Key}:Enabled").Exists()) continue;
var enabled = configuration.GetValue<bool>($"{feature.Key}:Enabled");
if (!enabled) continue;
var opts = new Dictionary<string, string>();
var config = configuration.GetSection($"{feature.Key}:Options");
config.Bind(opts);
var name = feature.Key.Replace($"{elsaFeaturesSection}:", string.Empty);
ElsaOptions.FeatureOptions.Features.Add(
new FeatureOption
{
Name = name,
Enabled = enabled,
Options = opts
});
}
return this;
}
public ElsaOptionsBuilder AddActivity<T>() where T : IActivity => AddActivity(typeof(T));
public ElsaOptionsBuilder AddActivity(Type activityType)

View file

@ -15,17 +15,18 @@ namespace Elsa
public static ElsaOptionsBuilder AddFeatures(this ElsaOptionsBuilder builder, IEnumerable<Assembly> assemblies, IConfiguration configuration)
{
if (builder.ElsaOptions.FeatureOptions.Features == null!) // Null when configuration binding finds an empty array.
ParseFeatures(configuration);
if (EnabledFeatures == null!) // Null when configuration binding finds an empty array.
return builder;
var enabledFeatures = builder.ElsaOptions.FeatureOptions.Features.ToHashSet();
var enabledFeatures = EnabledFeatures.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<FeatureAttribute>()
let enabledFeature = enabledFeatures.FirstOrDefault(x => x.Name == featureAttribute.FeatureName)
where featureAttribute != null && enabledFeature != null
where featureAttribute != null && enabledFeatures.Contains(featureAttribute.FeatureName)
select type;
var startupTypes = startupTypesQuery.ToList();
@ -39,7 +40,38 @@ namespace Elsa
return builder;
}
private static void ParseFeatures(IConfiguration configuration)
{
var elsaFeaturesSection = "Elsa:Features";
EnabledFeatures = new List<string>();
var features = configuration.GetSection(elsaFeaturesSection).AsEnumerable();
foreach (var feature in features)
{
var explEnabled = false;
var implEnabled = false;
if (configuration.GetSection($"{feature.Key}:Enabled").Exists())
{
bool.TryParse(configuration.GetValue<string>($"{feature.Key}:Enabled"), out explEnabled);
}
else if (!feature.Key.EndsWith(":Enabled"))
{
bool.TryParse(configuration.GetValue<string>($"{feature.Key}"), out implEnabled);
}
if (!explEnabled && !implEnabled) continue;
var featureName = feature.Key.Replace($"{elsaFeaturesSection}:", string.Empty);
EnabledFeatures.Add(featureName);
}
}
private static IEnumerable<Assembly> GetAssemblies(IEnumerable<Type> assemblyMarkerTypes) => assemblyMarkerTypes.Select(x => x.Assembly).Distinct();
private static ICollection<string>? EnabledFeatures { get; set; }
}
}

View file

@ -1,10 +0,0 @@
using System.Collections.Generic;
using Elsa.Models;
namespace Elsa
{
public class FeatureOptions
{
public ICollection<FeatureOption>? Features { get; set; }
}
}

View file

@ -1,11 +0,0 @@
using System.Collections.Generic;
namespace Elsa.Models
{
public class FeatureOption
{
public string Name { get; set; } = default!;
public bool Enabled { get; set; } = default!;
public Dictionary<string, string>? Options { get; set; }
}
}

View file

@ -13,8 +13,8 @@ namespace Elsa.Persistence.EntityFramework.Core
public override void ConfigureElsa(ElsaOptionsBuilder elsa, IConfiguration configuration)
{
var section = configuration.GetSection($"Elsa:Features:Persistence:EntityFrameworkCore:{ProviderName}");
var connectionStringName = section.GetValue<string>("Options:ConnectionStringName");
var connectionString = section.GetValue<string>("Options:ConnectionString");
var connectionStringName = section.GetValue<string>("ConnectionStringName");
var connectionString = section.GetValue<string>("ConnectionString");
if (string.IsNullOrWhiteSpace(connectionString))
{

View file

@ -10,8 +10,8 @@ namespace Elsa.Persistence.MongoDb
public override void ConfigureElsa(ElsaOptionsBuilder elsa, IConfiguration configuration)
{
var section = configuration.GetSection($"Elsa:Features:Persistence:MongoDb");
var connectionStringName = section.GetValue<string>("Options:ConnectionStringName");
var connectionString = section.GetValue<string>("Options:ConnectionString");
var connectionStringName = section.GetValue<string>("ConnectionStringName");
var connectionString = section.GetValue<string>("ConnectionString");
if (string.IsNullOrWhiteSpace(connectionString))
{

View file

@ -45,8 +45,8 @@ namespace Elsa.Persistence.YesSql
public override void ConfigureElsa(ElsaOptionsBuilder elsa, IConfiguration configuration)
{
var section = configuration.GetSection($"Elsa:Features:Persistence:YesSql:{ProviderName}");
var connectionStringName = section.GetValue<string>("Options:ConnectionStringName");
var connectionString = section.GetValue<string>("Options:ConnectionString");
var connectionStringName = section.GetValue<string>("ConnectionStringName");
var connectionString = section.GetValue<string>("ConnectionString");
if (string.IsNullOrWhiteSpace(connectionString))
{

View file

@ -36,7 +36,6 @@ namespace ElsaDashboard.Samples.AspNetCore.Monolith
.AddQuartzTemporalActivities()
.AddJavaScriptActivities()
.AddActivitiesFrom<Startup>()
.ConfigureFeatures(Configuration)
.AddFeatures(new[] { typeof(Startup) }, Configuration)
);

View file

@ -66,7 +66,6 @@ namespace Elsa.Samples.Server.Host
.AddElsa(elsa => elsa
.AddActivitiesFrom<Startup>()
.AddWorkflowsFrom<Startup>()
.ConfigureFeatures(Configuration)
.AddFeatures(startups, Configuration)
.ConfigureWorkflowChannels(options => elsaSection.GetSection("WorkflowChannels").Bind(options))
);

View file

@ -21,45 +21,21 @@
"Features": {
"Persistence:EntityFrameworkCore:Sqlite": {
"Enabled": "true",
"Options": {
"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"
"ConnectionStringName": "Sqlite"
},
"Dispatcher:Hangfire": true,
"Console": true,
"Http": true,
"Email": true,
"Temporal:Quartz": true,
"JavaScript:Activities": true,
"UserTask": true,
"Conductor": true,
"Telnyx": true,
"Webhooks": true,
"Webhooks:Persistence:EntityFrameworkCore:Sqlite": {
"Enabled": "true",
"Options": {
"ConnectionStringName": "Sqlite"
}
"ConnectionStringName": "Sqlite"
}
},
"WorkflowChannels": {