diff --git a/src/activities/Elsa.Activities.Console/ConsoleStartup.cs b/src/activities/Elsa.Activities.Console/ConsoleStartup.cs
new file mode 100644
index 000000000..d76e3a4f3
--- /dev/null
+++ b/src/activities/Elsa.Activities.Console/ConsoleStartup.cs
@@ -0,0 +1,14 @@
+using Elsa.Attributes;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Elsa.Activities.Console
+{
+ [Feature("Console")]
+ public class ConsoleStartup
+ {
+ public void ConfigureElsa(ElsaOptionsBuilder elsa)
+ {
+ elsa.AddConsoleActivities();
+ }
+ }
+}
diff --git a/src/activities/Elsa.Activities.Console/IsExternalInit.cs b/src/activities/Elsa.Activities.Console/IsExternalInit.cs
new file mode 100644
index 000000000..8ce226317
--- /dev/null
+++ b/src/activities/Elsa.Activities.Console/IsExternalInit.cs
@@ -0,0 +1,17 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.ComponentModel;
+
+// ReSharper disable once CheckNamespace
+namespace System.Runtime.CompilerServices
+{
+ ///
+ /// Reserved to be used by the compiler for tracking metadata.
+ /// This class should not be used by developers in source code.
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ internal static class IsExternalInit
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/activities/webhooks/Elsa.Activities.Webhooks/Elsa.Activities.Webhooks.csproj b/src/activities/webhooks/Elsa.Activities.Webhooks/Elsa.Activities.Webhooks.csproj
index 31ba5a08f..911e7bf4d 100644
--- a/src/activities/webhooks/Elsa.Activities.Webhooks/Elsa.Activities.Webhooks.csproj
+++ b/src/activities/webhooks/Elsa.Activities.Webhooks/Elsa.Activities.Webhooks.csproj
@@ -1,4 +1,4 @@
-
+
@@ -35,6 +35,11 @@
+
+
+
+
+
diff --git a/src/activities/webhooks/Elsa.Activities.Webhooks/Extensions/WebhookServiceCollectionExtensions.cs b/src/activities/webhooks/Elsa.Activities.Webhooks/Extensions/WebhookServiceCollectionExtensions.cs
new file mode 100644
index 000000000..2d8177efb
--- /dev/null
+++ b/src/activities/webhooks/Elsa.Activities.Webhooks/Extensions/WebhookServiceCollectionExtensions.cs
@@ -0,0 +1,232 @@
+using System;
+using Elsa.Runtime;
+using Elsa.Webhooks.Persistence.EntityFramework.Core;
+using Elsa.Webhooks.Persistence.EntityFramework.Core.Services;
+using Elsa.Webhooks.Persistence.EntityFramework.Core.StartupTasks;
+using Elsa.Webhooks.Persistence.EntityFramework.Core.Stores;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.DependencyInjection;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Elsa.Activities.Webhooks.Extensions
+{
+ public static class WebhookServiceCollectionExtensions
+ {
+ ///
+ /// Configures Elsa to use Entity Framework Core for persistence, using pooled DB Context instances.
+ ///
+ ///
+ ///
+ /// Pooled DB Context instances is a performance optimisation which is documented in more detail at
+ /// https://docs.microsoft.com/en-us/ef/core/performance/advanced-performance-topics?tabs=with-constant#dbcontext-pooling.
+ ///
+ ///
+ /// An Elsa options builder
+ /// A configuration builder callback
+ /// If true then database migrations will be auto-executed on startup
+ /// The Elsa options builder, so calls may be chained
+ public static WebhookOptionsBuilder UseEntityFrameworkPersistence(this WebhookOptionsBuilder webhookOptions,
+ Action configure,
+ bool autoRunMigrations = true) =>
+ webhookOptions.UseEntityFrameworkPersistence(configure, autoRunMigrations);
+
+ ///
+ /// Configures Elsa to use Entity Framework Core for persistence, using pooled DB Context instances.
+ ///
+ ///
+ ///
+ /// Pooled DB Context instances is a performance optimisation which is documented in more detail at
+ /// https://docs.microsoft.com/en-us/ef/core/performance/advanced-performance-topics?tabs=with-constant#dbcontext-pooling.
+ ///
+ ///
+ /// An Elsa options builder
+ /// A configuration builder callback
+ /// If true then database migrations will be auto-executed on startup
+ /// The concrete type of to use.
+ /// The Elsa options builder, so calls may be chained
+ public static WebhookOptionsBuilder UseEntityFrameworkPersistence(this WebhookOptionsBuilder webhookOptions,
+ Action configure,
+ bool autoRunMigrations = true) where TWebhookContext : WebhookContext =>
+ webhookOptions.UseEntityFrameworkPersistence((_, builder) => configure(builder), autoRunMigrations);
+
+ ///
+ /// Configures Elsa to use Entity Framework Core for persistence, using pooled DB Context instances.
+ ///
+ ///
+ ///
+ /// Pooled DB Context instances is a performance optimisation which is documented in more detail at
+ /// https://docs.microsoft.com/en-us/ef/core/performance/advanced-performance-topics?tabs=with-constant#dbcontext-pooling.
+ ///
+ ///
+ /// An Elsa options builder
+ /// A configuration builder callback, which also provides access to a service provider
+ /// If true then database migrations will be auto-executed on startup
+ /// The Elsa options builder, so calls may be chained
+ public static WebhookOptionsBuilder UseEntityFrameworkPersistence(this WebhookOptionsBuilder webhookOptions,
+ Action configure,
+ bool autoRunMigrations = true) =>
+ webhookOptions.UseEntityFrameworkPersistence(configure, autoRunMigrations);
+
+ ///
+ /// Configures Elsa to use Entity Framework Core for persistence, using pooled DB Context instances.
+ ///
+ ///
+ ///
+ /// Pooled DB Context instances is a performance optimisation which is documented in more detail at
+ /// https://docs.microsoft.com/en-us/ef/core/performance/advanced-performance-topics?tabs=with-constant#dbcontext-pooling.
+ ///
+ ///
+ /// An Elsa options builder
+ /// A configuration builder callback, which also provides access to a service provider
+ /// If true then database migrations will be auto-executed on startup
+ /// The concrete type of to use.
+ /// The Elsa options builder, so calls may be chained
+ public static WebhookOptionsBuilder UseEntityFrameworkPersistence(this WebhookOptionsBuilder webhookOptions,
+ Action configure,
+ bool autoRunMigrations = true) where TWebhookContext : WebhookContext =>
+ UseEntityFrameworkPersistence(webhookOptions, configure, autoRunMigrations, true, ServiceLifetime.Singleton);
+
+ ///
+ /// Configures Elsa to use Entity Framework Core for persistence, without using pooled DB Context instances.
+ ///
+ ///
+ ///
+ /// Use this method when you do not wish to use DB connection pooling, such as when integrating with a multi-tenant
+ /// application, where re-use of DB Context objects is impractical.
+ ///
+ ///
+ /// Although auto-running of migrations is supported in this scenario, use this with caution. When pooling is not in use and each instance of
+ /// the DB Context may differ, it is not feasible to try to automatically migrate them.
+ /// Your application is ultimately responsible for executing the contents of the class in a manner
+ /// which is suitable for your use-case.
+ ///
+ ///
+ /// An Elsa options builder
+ /// A configuration builder callback
+ /// The service lifetime which will be used for each DB Context instance
+ /// If true then database migrations will be auto-executed on startup
+ /// The Elsa options builder, so calls may be chained
+ public static WebhookOptionsBuilder UseNonPooledEntityFrameworkPersistence(this WebhookOptionsBuilder webhookOptions,
+ Action configure,
+ ServiceLifetime serviceLifetime = ServiceLifetime.Singleton,
+ bool autoRunMigrations = false) =>
+ webhookOptions.UseNonPooledEntityFrameworkPersistence(configure, serviceLifetime, autoRunMigrations);
+
+ ///
+ /// Configures Elsa to use Entity Framework Core for persistence, without using pooled DB Context instances.
+ ///
+ ///
+ ///
+ /// Use this method when you do not wish to use DB connection pooling, such as when integrating with a multi-tenant
+ /// application, where re-use of DB Context objects is impractical.
+ ///
+ ///
+ /// Although auto-running of migrations is supported in this scenario, use this with caution. When pooling is not in use and each instance of
+ /// the DB Context may differ, it is not feasible to try to automatically migrate them.
+ /// Your application is ultimately responsible for executing the contents of the class in a manner
+ /// which is suitable for your use-case.
+ ///
+ ///
+ /// An Elsa options builder
+ /// A configuration builder callback
+ /// The service lifetime which will be used for each DB Context instance
+ /// If true then database migrations will be auto-executed on startup
+ /// The concrete type of to use.
+ /// The Elsa options builder, so calls may be chained
+ public static WebhookOptionsBuilder UseNonPooledEntityFrameworkPersistence(this WebhookOptionsBuilder webhookOptions,
+ Action configure,
+ ServiceLifetime serviceLifetime = ServiceLifetime.Singleton,
+ bool autoRunMigrations = false) where TWebhookContext : WebhookContext =>
+ webhookOptions.UseNonPooledEntityFrameworkPersistence((_, builder) => configure(builder), serviceLifetime, autoRunMigrations);
+
+ ///
+ /// Configures Elsa to use Entity Framework Core for persistence, without using pooled DB Context instances.
+ ///
+ ///
+ ///
+ /// Use this method when you do not wish to use DB connection pooling, such as when integrating with a multi-tenant
+ /// application, where re-use of DB Context objects is impractical.
+ ///
+ ///
+ /// Although auto-running of migrations is supported in this scenario, use this with caution. When pooling is not in use and each instance of
+ /// the DB Context may differ, it is not feasible to try to automatically migrate them.
+ /// Your application is ultimately responsible for executing the contents of the class in a manner
+ /// which is suitable for your use-case.
+ ///
+ ///
+ /// An Elsa options builder
+ /// A configuration builder callback, which also provides access to a service provider
+ /// The service lifetime which will be used for each DB Context instance
+ /// If true then database migrations will be auto-executed on startup
+ /// The Elsa options builder, so calls may be chained
+ public static WebhookOptionsBuilder UseNonPooledEntityFrameworkPersistence(this WebhookOptionsBuilder webhookOptions,
+ Action configure,
+ ServiceLifetime serviceLifetime = ServiceLifetime.Singleton,
+ bool autoRunMigrations = false) =>
+ webhookOptions.UseNonPooledEntityFrameworkPersistence(configure, serviceLifetime, autoRunMigrations);
+
+ ///
+ /// Configures Elsa to use Entity Framework Core for persistence, without using pooled DB Context instances.
+ ///
+ ///
+ ///
+ /// Use this method when you do not wish to use DB connection pooling, such as when integrating with a multi-tenant
+ /// application, where re-use of DB Context objects is impractical.
+ ///
+ ///
+ /// Although auto-running of migrations is supported in this scenario, use this with caution. When pooling is not in use and each instance of
+ /// the DB Context may differ, it is not feasible to try to automatically migrate them.
+ /// Your application is ultimately responsible for executing the contents of the class in a manner
+ /// which is suitable for your use-case.
+ ///
+ ///
+ /// An Elsa options builder
+ /// A configuration builder callback, which also provides access to a service provider
+ /// The service lifetime which will be used for each DB Context instance
+ /// If true then database migrations will be auto-executed on startup
+ /// The concrete type of to use.
+ /// The Elsa options builder, so calls may be chained
+ public static WebhookOptionsBuilder UseNonPooledEntityFrameworkPersistence(this WebhookOptionsBuilder webhookOptions,
+ Action configure,
+ ServiceLifetime serviceLifetime = ServiceLifetime.Singleton,
+ bool autoRunMigrations = false) where TWebhookContext : WebhookContext =>
+ UseEntityFrameworkPersistence(webhookOptions, configure, autoRunMigrations, false, serviceLifetime);
+
+ static WebhookOptionsBuilder UseEntityFrameworkPersistence(WebhookOptionsBuilder webhookOptions,
+ Action configure,
+ bool autoRunMigrations,
+ bool useContextPooling,
+ ServiceLifetime serviceLifetime) where TWebhookContext : WebhookContext
+ {
+ /* Auto-running migrations is intentionally unavailable when not using context pooling.
+ * When we aren't using pooling then it probably means that each DB Context is different
+ * in some manner. That could easily mean the connection strings (IE: Contexts might not
+ * all connect to the same DB). In that case, without further logic (which can't be
+ * pre-empted by Elsa), we can't be sure we're connecting to the right DBs when running
+ * migrations.
+ *
+ * It's much more sane just to explicitly not-support it and leave it to the app developer.
+ * They can run their own migrations in line with their own logic.
+ */
+
+ if (useContextPooling)
+ webhookOptions.Services.AddPooledDbContextFactory(configure);
+ else
+ webhookOptions.Services.AddDbContextFactory(configure, serviceLifetime);
+
+ webhookOptions.Services
+ .AddSingleton>()
+ .AddScoped();
+
+ if (autoRunMigrations)
+ webhookOptions.Services.AddStartupTask();
+
+ webhookOptions.UseWebhookDefinitionStore(sp => sp.GetRequiredService());
+
+ return webhookOptions;
+ }
+ }
+}
diff --git a/src/activities/webhooks/Elsa.Activities.Webhooks/WebhookStartup.cs b/src/activities/webhooks/Elsa.Activities.Webhooks/WebhookStartup.cs
new file mode 100644
index 000000000..fbd0c21c9
--- /dev/null
+++ b/src/activities/webhooks/Elsa.Activities.Webhooks/WebhookStartup.cs
@@ -0,0 +1,16 @@
+using Elsa.Activities.Webhooks.Extensions;
+using Elsa.Attributes;
+using Elsa.Webhooks.Persistence.EntityFramework.Sqlite;
+
+namespace Elsa.Activities.Webhooks
+{
+ [Feature("Webhook")]
+ public class WebhookStartup
+ {
+ //, IConfiguration configuration
+ public void ConfigureElsa(ElsaOptionsBuilder elsa)
+ {
+ elsa.AddWebhooks(webhooks => webhooks.UseEntityFrameworkPersistence(ef => ef.UseWebhookSqlite()));
+ }
+ }
+}
diff --git a/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/Elsa.Webhooks.Persistence.EntityFramework.Core.csproj b/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/Elsa.Webhooks.Persistence.EntityFramework.Core.csproj
index c6b9f6818..f35f7aca7 100644
--- a/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/Elsa.Webhooks.Persistence.EntityFramework.Core.csproj
+++ b/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/Elsa.Webhooks.Persistence.EntityFramework.Core.csproj
@@ -19,7 +19,6 @@
-
diff --git a/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/Extensions/WebhookServiceCollectionExtensions.cs b/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/Extensions/WebhookServiceCollectionExtensions.cs
index 729ed83ee..e2f321776 100644
--- a/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/Extensions/WebhookServiceCollectionExtensions.cs
+++ b/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/Extensions/WebhookServiceCollectionExtensions.cs
@@ -1,228 +1,228 @@
-using System;
-using Elsa.Webhooks.Persistence.EntityFramework.Core.Services;
-using Elsa.Webhooks.Persistence.EntityFramework.Core.StartupTasks;
-using Elsa.Webhooks.Persistence.EntityFramework.Core.Stores;
-using Elsa.Activities.Webhooks;
-using Elsa.Runtime;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.DependencyInjection;
+//using System;
+//using Elsa.Webhooks.Persistence.EntityFramework.Core.Services;
+//using Elsa.Webhooks.Persistence.EntityFramework.Core.StartupTasks;
+//using Elsa.Webhooks.Persistence.EntityFramework.Core.Stores;
+//using Elsa.Activities.Webhooks;
+//using Elsa.Runtime;
+//using Microsoft.EntityFrameworkCore;
+//using Microsoft.Extensions.DependencyInjection;
-namespace Elsa.Webhooks.Persistence.EntityFramework.Core.Extensions
-{
- public static class WebhookServiceCollectionExtensions
- {
- ///
- /// Configures Elsa to use Entity Framework Core for persistence, using pooled DB Context instances.
- ///
- ///
- ///
- /// Pooled DB Context instances is a performance optimisation which is documented in more detail at
- /// https://docs.microsoft.com/en-us/ef/core/performance/advanced-performance-topics?tabs=with-constant#dbcontext-pooling.
- ///
- ///
- /// An Elsa options builder
- /// A configuration builder callback
- /// If true then database migrations will be auto-executed on startup
- /// The Elsa options builder, so calls may be chained
- public static WebhookOptionsBuilder UseEntityFrameworkPersistence(this WebhookOptionsBuilder webhookOptions,
- Action configure,
- bool autoRunMigrations = true) =>
- webhookOptions.UseEntityFrameworkPersistence(configure, autoRunMigrations);
+//namespace Elsa.Webhooks.Persistence.EntityFramework.Core.Extensions
+//{
+// public static class WebhookServiceCollectionExtensions
+// {
+// ///
+// /// Configures Elsa to use Entity Framework Core for persistence, using pooled DB Context instances.
+// ///
+// ///
+// ///
+// /// Pooled DB Context instances is a performance optimisation which is documented in more detail at
+// /// https://docs.microsoft.com/en-us/ef/core/performance/advanced-performance-topics?tabs=with-constant#dbcontext-pooling.
+// ///
+// ///
+// /// An Elsa options builder
+// /// A configuration builder callback
+// /// If true then database migrations will be auto-executed on startup
+// /// The Elsa options builder, so calls may be chained
+// public static WebhookOptionsBuilder UseEntityFrameworkPersistence(this WebhookOptionsBuilder webhookOptions,
+// Action configure,
+// bool autoRunMigrations = true) =>
+// webhookOptions.UseEntityFrameworkPersistence(configure, autoRunMigrations);
- ///
- /// Configures Elsa to use Entity Framework Core for persistence, using pooled DB Context instances.
- ///
- ///
- ///
- /// Pooled DB Context instances is a performance optimisation which is documented in more detail at
- /// https://docs.microsoft.com/en-us/ef/core/performance/advanced-performance-topics?tabs=with-constant#dbcontext-pooling.
- ///
- ///
- /// An Elsa options builder
- /// A configuration builder callback
- /// If true then database migrations will be auto-executed on startup
- /// The concrete type of to use.
- /// The Elsa options builder, so calls may be chained
- public static WebhookOptionsBuilder UseEntityFrameworkPersistence(this WebhookOptionsBuilder webhookOptions,
- Action configure,
- bool autoRunMigrations = true) where TWebhookContext : WebhookContext =>
- webhookOptions.UseEntityFrameworkPersistence((_, builder) => configure(builder), autoRunMigrations);
+// ///
+// /// Configures Elsa to use Entity Framework Core for persistence, using pooled DB Context instances.
+// ///
+// ///
+// ///
+// /// Pooled DB Context instances is a performance optimisation which is documented in more detail at
+// /// https://docs.microsoft.com/en-us/ef/core/performance/advanced-performance-topics?tabs=with-constant#dbcontext-pooling.
+// ///
+// ///
+// /// An Elsa options builder
+// /// A configuration builder callback
+// /// If true then database migrations will be auto-executed on startup
+// /// The concrete type of to use.
+// /// The Elsa options builder, so calls may be chained
+// public static WebhookOptionsBuilder UseEntityFrameworkPersistence(this WebhookOptionsBuilder webhookOptions,
+// Action configure,
+// bool autoRunMigrations = true) where TWebhookContext : WebhookContext =>
+// webhookOptions.UseEntityFrameworkPersistence((_, builder) => configure(builder), autoRunMigrations);
- ///
- /// Configures Elsa to use Entity Framework Core for persistence, using pooled DB Context instances.
- ///
- ///
- ///
- /// Pooled DB Context instances is a performance optimisation which is documented in more detail at
- /// https://docs.microsoft.com/en-us/ef/core/performance/advanced-performance-topics?tabs=with-constant#dbcontext-pooling.
- ///
- ///
- /// An Elsa options builder
- /// A configuration builder callback, which also provides access to a service provider
- /// If true then database migrations will be auto-executed on startup
- /// The Elsa options builder, so calls may be chained
- public static WebhookOptionsBuilder UseEntityFrameworkPersistence(this WebhookOptionsBuilder webhookOptions,
- Action configure,
- bool autoRunMigrations = true) =>
- webhookOptions.UseEntityFrameworkPersistence(configure, autoRunMigrations);
+// ///
+// /// Configures Elsa to use Entity Framework Core for persistence, using pooled DB Context instances.
+// ///
+// ///
+// ///
+// /// Pooled DB Context instances is a performance optimisation which is documented in more detail at
+// /// https://docs.microsoft.com/en-us/ef/core/performance/advanced-performance-topics?tabs=with-constant#dbcontext-pooling.
+// ///
+// ///
+// /// An Elsa options builder
+// /// A configuration builder callback, which also provides access to a service provider
+// /// If true then database migrations will be auto-executed on startup
+// /// The Elsa options builder, so calls may be chained
+// public static WebhookOptionsBuilder UseEntityFrameworkPersistence(this WebhookOptionsBuilder webhookOptions,
+// Action configure,
+// bool autoRunMigrations = true) =>
+// webhookOptions.UseEntityFrameworkPersistence(configure, autoRunMigrations);
- ///
- /// Configures Elsa to use Entity Framework Core for persistence, using pooled DB Context instances.
- ///
- ///
- ///
- /// Pooled DB Context instances is a performance optimisation which is documented in more detail at
- /// https://docs.microsoft.com/en-us/ef/core/performance/advanced-performance-topics?tabs=with-constant#dbcontext-pooling.
- ///
- ///
- /// An Elsa options builder
- /// A configuration builder callback, which also provides access to a service provider
- /// If true then database migrations will be auto-executed on startup
- /// The concrete type of to use.
- /// The Elsa options builder, so calls may be chained
- public static WebhookOptionsBuilder UseEntityFrameworkPersistence(this WebhookOptionsBuilder webhookOptions,
- Action configure,
- bool autoRunMigrations = true) where TWebhookContext : WebhookContext =>
- UseEntityFrameworkPersistence(webhookOptions, configure, autoRunMigrations, true, ServiceLifetime.Singleton);
+// ///
+// /// Configures Elsa to use Entity Framework Core for persistence, using pooled DB Context instances.
+// ///
+// ///
+// ///
+// /// Pooled DB Context instances is a performance optimisation which is documented in more detail at
+// /// https://docs.microsoft.com/en-us/ef/core/performance/advanced-performance-topics?tabs=with-constant#dbcontext-pooling.
+// ///
+// ///
+// /// An Elsa options builder
+// /// A configuration builder callback, which also provides access to a service provider
+// /// If true then database migrations will be auto-executed on startup
+// /// The concrete type of to use.
+// /// The Elsa options builder, so calls may be chained
+// public static WebhookOptionsBuilder UseEntityFrameworkPersistence(this WebhookOptionsBuilder webhookOptions,
+// Action configure,
+// bool autoRunMigrations = true) where TWebhookContext : WebhookContext =>
+// UseEntityFrameworkPersistence(webhookOptions, configure, autoRunMigrations, true, ServiceLifetime.Singleton);
- ///
- /// Configures Elsa to use Entity Framework Core for persistence, without using pooled DB Context instances.
- ///
- ///
- ///
- /// Use this method when you do not wish to use DB connection pooling, such as when integrating with a multi-tenant
- /// application, where re-use of DB Context objects is impractical.
- ///
- ///
- /// Although auto-running of migrations is supported in this scenario, use this with caution. When pooling is not in use and each instance of
- /// the DB Context may differ, it is not feasible to try to automatically migrate them.
- /// Your application is ultimately responsible for executing the contents of the class in a manner
- /// which is suitable for your use-case.
- ///
- ///
- /// An Elsa options builder
- /// A configuration builder callback
- /// The service lifetime which will be used for each DB Context instance
- /// If true then database migrations will be auto-executed on startup
- /// The Elsa options builder, so calls may be chained
- public static WebhookOptionsBuilder UseNonPooledEntityFrameworkPersistence(this WebhookOptionsBuilder webhookOptions,
- Action configure,
- ServiceLifetime serviceLifetime = ServiceLifetime.Singleton,
- bool autoRunMigrations = false) =>
- webhookOptions.UseNonPooledEntityFrameworkPersistence(configure, serviceLifetime, autoRunMigrations);
+// ///
+// /// Configures Elsa to use Entity Framework Core for persistence, without using pooled DB Context instances.
+// ///
+// ///
+// ///
+// /// Use this method when you do not wish to use DB connection pooling, such as when integrating with a multi-tenant
+// /// application, where re-use of DB Context objects is impractical.
+// ///
+// ///
+// /// Although auto-running of migrations is supported in this scenario, use this with caution. When pooling is not in use and each instance of
+// /// the DB Context may differ, it is not feasible to try to automatically migrate them.
+// /// Your application is ultimately responsible for executing the contents of the class in a manner
+// /// which is suitable for your use-case.
+// ///
+// ///
+// /// An Elsa options builder
+// /// A configuration builder callback
+// /// The service lifetime which will be used for each DB Context instance
+// /// If true then database migrations will be auto-executed on startup
+// /// The Elsa options builder, so calls may be chained
+// public static WebhookOptionsBuilder UseNonPooledEntityFrameworkPersistence(this WebhookOptionsBuilder webhookOptions,
+// Action configure,
+// ServiceLifetime serviceLifetime = ServiceLifetime.Singleton,
+// bool autoRunMigrations = false) =>
+// webhookOptions.UseNonPooledEntityFrameworkPersistence(configure, serviceLifetime, autoRunMigrations);
- ///
- /// Configures Elsa to use Entity Framework Core for persistence, without using pooled DB Context instances.
- ///
- ///
- ///
- /// Use this method when you do not wish to use DB connection pooling, such as when integrating with a multi-tenant
- /// application, where re-use of DB Context objects is impractical.
- ///
- ///
- /// Although auto-running of migrations is supported in this scenario, use this with caution. When pooling is not in use and each instance of
- /// the DB Context may differ, it is not feasible to try to automatically migrate them.
- /// Your application is ultimately responsible for executing the contents of the class in a manner
- /// which is suitable for your use-case.
- ///
- ///
- /// An Elsa options builder
- /// A configuration builder callback
- /// The service lifetime which will be used for each DB Context instance
- /// If true then database migrations will be auto-executed on startup
- /// The concrete type of to use.
- /// The Elsa options builder, so calls may be chained
- public static WebhookOptionsBuilder UseNonPooledEntityFrameworkPersistence(this WebhookOptionsBuilder webhookOptions,
- Action configure,
- ServiceLifetime serviceLifetime = ServiceLifetime.Singleton,
- bool autoRunMigrations = false) where TWebhookContext : WebhookContext =>
- webhookOptions.UseNonPooledEntityFrameworkPersistence((_, builder) => configure(builder), serviceLifetime, autoRunMigrations);
+// ///
+// /// Configures Elsa to use Entity Framework Core for persistence, without using pooled DB Context instances.
+// ///
+// ///
+// ///
+// /// Use this method when you do not wish to use DB connection pooling, such as when integrating with a multi-tenant
+// /// application, where re-use of DB Context objects is impractical.
+// ///
+// ///
+// /// Although auto-running of migrations is supported in this scenario, use this with caution. When pooling is not in use and each instance of
+// /// the DB Context may differ, it is not feasible to try to automatically migrate them.
+// /// Your application is ultimately responsible for executing the contents of the class in a manner
+// /// which is suitable for your use-case.
+// ///
+// ///
+// /// An Elsa options builder
+// /// A configuration builder callback
+// /// The service lifetime which will be used for each DB Context instance
+// /// If true then database migrations will be auto-executed on startup
+// /// The concrete type of to use.
+// /// The Elsa options builder, so calls may be chained
+// public static WebhookOptionsBuilder UseNonPooledEntityFrameworkPersistence(this WebhookOptionsBuilder webhookOptions,
+// Action configure,
+// ServiceLifetime serviceLifetime = ServiceLifetime.Singleton,
+// bool autoRunMigrations = false) where TWebhookContext : WebhookContext =>
+// webhookOptions.UseNonPooledEntityFrameworkPersistence((_, builder) => configure(builder), serviceLifetime, autoRunMigrations);
- ///
- /// Configures Elsa to use Entity Framework Core for persistence, without using pooled DB Context instances.
- ///
- ///
- ///
- /// Use this method when you do not wish to use DB connection pooling, such as when integrating with a multi-tenant
- /// application, where re-use of DB Context objects is impractical.
- ///
- ///
- /// Although auto-running of migrations is supported in this scenario, use this with caution. When pooling is not in use and each instance of
- /// the DB Context may differ, it is not feasible to try to automatically migrate them.
- /// Your application is ultimately responsible for executing the contents of the class in a manner
- /// which is suitable for your use-case.
- ///
- ///
- /// An Elsa options builder
- /// A configuration builder callback, which also provides access to a service provider
- /// The service lifetime which will be used for each DB Context instance
- /// If true then database migrations will be auto-executed on startup
- /// The Elsa options builder, so calls may be chained
- public static WebhookOptionsBuilder UseNonPooledEntityFrameworkPersistence(this WebhookOptionsBuilder webhookOptions,
- Action configure,
- ServiceLifetime serviceLifetime = ServiceLifetime.Singleton,
- bool autoRunMigrations = false) =>
- webhookOptions.UseNonPooledEntityFrameworkPersistence(configure, serviceLifetime, autoRunMigrations);
+// ///
+// /// Configures Elsa to use Entity Framework Core for persistence, without using pooled DB Context instances.
+// ///
+// ///
+// ///
+// /// Use this method when you do not wish to use DB connection pooling, such as when integrating with a multi-tenant
+// /// application, where re-use of DB Context objects is impractical.
+// ///
+// ///
+// /// Although auto-running of migrations is supported in this scenario, use this with caution. When pooling is not in use and each instance of
+// /// the DB Context may differ, it is not feasible to try to automatically migrate them.
+// /// Your application is ultimately responsible for executing the contents of the class in a manner
+// /// which is suitable for your use-case.
+// ///
+// ///
+// /// An Elsa options builder
+// /// A configuration builder callback, which also provides access to a service provider
+// /// The service lifetime which will be used for each DB Context instance
+// /// If true then database migrations will be auto-executed on startup
+// /// The Elsa options builder, so calls may be chained
+// public static WebhookOptionsBuilder UseNonPooledEntityFrameworkPersistence(this WebhookOptionsBuilder webhookOptions,
+// Action configure,
+// ServiceLifetime serviceLifetime = ServiceLifetime.Singleton,
+// bool autoRunMigrations = false) =>
+// webhookOptions.UseNonPooledEntityFrameworkPersistence(configure, serviceLifetime, autoRunMigrations);
- ///
- /// Configures Elsa to use Entity Framework Core for persistence, without using pooled DB Context instances.
- ///
- ///
- ///
- /// Use this method when you do not wish to use DB connection pooling, such as when integrating with a multi-tenant
- /// application, where re-use of DB Context objects is impractical.
- ///
- ///
- /// Although auto-running of migrations is supported in this scenario, use this with caution. When pooling is not in use and each instance of
- /// the DB Context may differ, it is not feasible to try to automatically migrate them.
- /// Your application is ultimately responsible for executing the contents of the class in a manner
- /// which is suitable for your use-case.
- ///
- ///
- /// An Elsa options builder
- /// A configuration builder callback, which also provides access to a service provider
- /// The service lifetime which will be used for each DB Context instance
- /// If true then database migrations will be auto-executed on startup
- /// The concrete type of to use.
- /// The Elsa options builder, so calls may be chained
- public static WebhookOptionsBuilder UseNonPooledEntityFrameworkPersistence(this WebhookOptionsBuilder webhookOptions,
- Action configure,
- ServiceLifetime serviceLifetime = ServiceLifetime.Singleton,
- bool autoRunMigrations = false) where TWebhookContext : WebhookContext =>
- UseEntityFrameworkPersistence(webhookOptions, configure, autoRunMigrations, false, serviceLifetime);
+// ///
+// /// Configures Elsa to use Entity Framework Core for persistence, without using pooled DB Context instances.
+// ///
+// ///
+// ///
+// /// Use this method when you do not wish to use DB connection pooling, such as when integrating with a multi-tenant
+// /// application, where re-use of DB Context objects is impractical.
+// ///
+// ///
+// /// Although auto-running of migrations is supported in this scenario, use this with caution. When pooling is not in use and each instance of
+// /// the DB Context may differ, it is not feasible to try to automatically migrate them.
+// /// Your application is ultimately responsible for executing the contents of the class in a manner
+// /// which is suitable for your use-case.
+// ///
+// ///
+// /// An Elsa options builder
+// /// A configuration builder callback, which also provides access to a service provider
+// /// The service lifetime which will be used for each DB Context instance
+// /// If true then database migrations will be auto-executed on startup
+// /// The concrete type of to use.
+// /// The Elsa options builder, so calls may be chained
+// public static WebhookOptionsBuilder UseNonPooledEntityFrameworkPersistence(this WebhookOptionsBuilder webhookOptions,
+// Action configure,
+// ServiceLifetime serviceLifetime = ServiceLifetime.Singleton,
+// bool autoRunMigrations = false) where TWebhookContext : WebhookContext =>
+// UseEntityFrameworkPersistence(webhookOptions, configure, autoRunMigrations, false, serviceLifetime);
- static WebhookOptionsBuilder UseEntityFrameworkPersistence(WebhookOptionsBuilder webhookOptions,
- Action configure,
- bool autoRunMigrations,
- bool useContextPooling,
- ServiceLifetime serviceLifetime) where TWebhookContext : WebhookContext
- {
- /* Auto-running migrations is intentionally unavailable when not using context pooling.
- * When we aren't using pooling then it probably means that each DB Context is different
- * in some manner. That could easily mean the connection strings (IE: Contexts might not
- * all connect to the same DB). In that case, without further logic (which can't be
- * pre-empted by Elsa), we can't be sure we're connecting to the right DBs when running
- * migrations.
- *
- * It's much more sane just to explicitly not-support it and leave it to the app developer.
- * They can run their own migrations in line with their own logic.
- */
+// static WebhookOptionsBuilder UseEntityFrameworkPersistence(WebhookOptionsBuilder webhookOptions,
+// Action configure,
+// bool autoRunMigrations,
+// bool useContextPooling,
+// ServiceLifetime serviceLifetime) where TWebhookContext : WebhookContext
+// {
+// /* Auto-running migrations is intentionally unavailable when not using context pooling.
+// * When we aren't using pooling then it probably means that each DB Context is different
+// * in some manner. That could easily mean the connection strings (IE: Contexts might not
+// * all connect to the same DB). In that case, without further logic (which can't be
+// * pre-empted by Elsa), we can't be sure we're connecting to the right DBs when running
+// * migrations.
+// *
+// * It's much more sane just to explicitly not-support it and leave it to the app developer.
+// * They can run their own migrations in line with their own logic.
+// */
- if (useContextPooling)
- webhookOptions.Services.AddPooledDbContextFactory(configure);
- else
- webhookOptions.Services.AddDbContextFactory(configure, serviceLifetime);
+// if (useContextPooling)
+// webhookOptions.Services.AddPooledDbContextFactory(configure);
+// else
+// webhookOptions.Services.AddDbContextFactory(configure, serviceLifetime);
- webhookOptions.Services
- .AddSingleton>()
- .AddScoped();
+// webhookOptions.Services
+// .AddSingleton>()
+// .AddScoped();
- if (autoRunMigrations)
- webhookOptions.Services.AddStartupTask();
+// if (autoRunMigrations)
+// webhookOptions.Services.AddStartupTask();
- webhookOptions.UseWebhookDefinitionStore(sp => sp.GetRequiredService());
+// webhookOptions.UseWebhookDefinitionStore(sp => sp.GetRequiredService());
- return webhookOptions;
- }
- }
-}
+// return webhookOptions;
+// }
+// }
+//}
diff --git a/src/core/Elsa.Abstractions/Attributes/FeatureAttribute.cs b/src/core/Elsa.Abstractions/Attributes/FeatureAttribute.cs
new file mode 100644
index 000000000..355c9d3a0
--- /dev/null
+++ b/src/core/Elsa.Abstractions/Attributes/FeatureAttribute.cs
@@ -0,0 +1,23 @@
+using System;
+
+namespace Elsa.Attributes
+{
+ ///
+ /// An attribute that can associate a service or component with
+ /// a specific feature by its name. This component will only
+ /// be used if the feature is enabled.
+ ///
+ [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
+ public class FeatureAttribute : Attribute
+ {
+ public FeatureAttribute(string featureName)
+ {
+ FeatureName = featureName;
+ }
+
+ ///
+ /// The name of the feature to assign the component to.
+ ///
+ public string FeatureName { get; set; }
+ }
+}
diff --git a/src/core/Elsa.Abstractions/Extensions/AssemblyExtensions.cs b/src/core/Elsa.Abstractions/Extensions/AssemblyExtensions.cs
index 51a209f66..9eff65df2 100644
--- a/src/core/Elsa.Abstractions/Extensions/AssemblyExtensions.cs
+++ b/src/core/Elsa.Abstractions/Extensions/AssemblyExtensions.cs
@@ -10,7 +10,9 @@ namespace Elsa
{
public static IEnumerable GetAllWithInterface(this Assembly assembly, Type @interface) => assembly.GetTypes().Where(t => t.IsClass && t.IsAbstract == false && t.GetInterfaces().Contains(@interface));
public static IEnumerable GetAllWithBaseClass(this Assembly assembly, Type baseClass) => assembly.GetTypes().Where(baseClass.IsAssignableFrom);
+ //public static IEnumerable GetAllWithAttribute(this Assembly assembly, Type attribute) => assembly.GetTypes().Where(t => t.GetCustomAttributes(typeof(attribute), true).Length > 0);
public static IEnumerable GetAllWithInterface(this Assembly assembly) => assembly.GetAllWithInterface(typeof(TType));
public static IEnumerable GetAllWithBaseClass(this Assembly assembly) => assembly.GetAllWithBaseClass(typeof(TType));
+ //public static IEnumerable GetAllWithAttribute(this Assembly assembly) => assembly.GetAllWithAttribute(typeof(TType));
}
}
diff --git a/src/core/Elsa.Core/ElsaOptionsBuilder.cs b/src/core/Elsa.Core/ElsaOptionsBuilder.cs
index 8a53fc742..387f8da96 100644
--- a/src/core/Elsa.Core/ElsaOptionsBuilder.cs
+++ b/src/core/Elsa.Core/ElsaOptionsBuilder.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
+using Elsa.Attributes;
using Elsa.Builders;
using Elsa.Caching;
using Elsa.Persistence;
@@ -56,6 +57,34 @@ namespace Elsa
return this;
}
+ public ElsaOptionsBuilder AddFeatures(IEnumerable assemblies, IEnumerable features)
+ {
+ foreach (Assembly assembly in assemblies)
+ {
+ foreach (Type type in assembly.GetTypes())
+ {
+ var attributes = type.GetCustomAttributes(typeof(FeatureAttribute), true);
+
+ foreach (Attribute attribute in attributes)
+ {
+ if (!features.Contains(((FeatureAttribute)attribute).FeatureName)) continue;
+
+ MethodInfo methodInfo = type.GetMethod("ConfigureElsa");
+
+ if (methodInfo != null)
+ {
+ object[] parametersArray = new object[] { this };
+ object classInstance = Activator.CreateInstance(type, null);
+ methodInfo.Invoke(classInstance, parametersArray);
+ }
+
+ }
+ }
+ }
+
+ return this;
+ }
+
public ElsaOptionsBuilder AddActivity() where T : IActivity => AddActivity(typeof(T));
public ElsaOptionsBuilder AddActivity(Type activityType)
diff --git a/src/samples/server/Elsa.Samples.Server.Host/Elsa.Samples.Server.Host.csproj b/src/samples/server/Elsa.Samples.Server.Host/Elsa.Samples.Server.Host.csproj
index a1da00d9c..5fbadf014 100644
--- a/src/samples/server/Elsa.Samples.Server.Host/Elsa.Samples.Server.Host.csproj
+++ b/src/samples/server/Elsa.Samples.Server.Host/Elsa.Samples.Server.Host.csproj
@@ -10,6 +10,7 @@
+
diff --git a/src/samples/server/Elsa.Samples.Server.Host/Startup.cs b/src/samples/server/Elsa.Samples.Server.Host/Startup.cs
index b469b0107..497bae87a 100644
--- a/src/samples/server/Elsa.Samples.Server.Host/Startup.cs
+++ b/src/samples/server/Elsa.Samples.Server.Host/Startup.cs
@@ -1,16 +1,21 @@
using Elsa.Activities.Conductor.Extensions;
using Elsa.Activities.UserTask.Extensions;
using Elsa.Activities.Webhooks.Extensions;
+using Elsa.Attributes;
using Elsa.Persistence.EntityFramework.Core.Extensions;
using Elsa.Persistence.EntityFramework.Sqlite;
using Elsa.Samples.Server.Host.Activities;
-using Elsa.Webhooks.Persistence.EntityFramework.Core.Extensions;
+//using Elsa.Webhooks.Persistence.EntityFramework.Core.Extensions;
using Elsa.Webhooks.Persistence.EntityFramework.Sqlite;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
namespace Elsa.Samples.Server.Host
{
@@ -34,6 +39,9 @@ namespace Elsa.Samples.Server.Host
services.AddControllers();
+ //List assemblies = Assembly.GetExecutingAssembly().GetReferencedAssemblies().Select((item) => Assembly.Load(item)).ToList();
+ List assemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();
+
services
.AddActivityPropertyOptionsProvider()
.AddRuntimeSelectItemsProvider()
@@ -46,7 +54,9 @@ namespace Elsa.Samples.Server.Host
//.UseRabbitMq(Configuration.GetConnectionString("RabbitMq"))
//.UseRebusCacheSignal()
//.UseRedisCacheSignal()
+
.AddConsoleActivities()
+
.AddHttpActivities(elsaSection.GetSection("Http").Bind)
.AddEmailActivities(elsaSection.GetSection("Smtp").Bind)
.AddQuartzTemporalActivities()
@@ -63,7 +73,9 @@ namespace Elsa.Samples.Server.Host
.AddConductorActivities(options => elsaSection.GetSection("Conductor").Bind(options))
.AddActivitiesFrom()
.AddWorkflowsFrom()
- .AddWebhooks(webhooks => webhooks.UseEntityFrameworkPersistence(ef => ef.UseWebhookSqlite()))
+ .AddFeatures(assemblies, elsaSection.GetSection("Features").Get>())
+
+ //.AddWebhooks(webhooks => webhooks.UseEntityFrameworkPersistence(ef => ef.UseWebhookSqlite()))
);
// Elsa API endpoints.
@@ -71,6 +83,8 @@ namespace Elsa.Samples.Server.Host
.AddElsaApiEndpoints()
.AddElsaSwagger();
+ //AddFeatures();
+
// Allow arbitrary client browser apps to access the API for demo purposes only.
// In a production environment, make sure to allow only origins you trust.
services.AddCors(cors => cors.AddDefaultPolicy(policy => policy.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin().WithExposedHeaders("Content-Disposition")));
@@ -91,5 +105,6 @@ namespace Elsa.Samples.Server.Host
.UseRouting()
.UseEndpoints(endpoints => { endpoints.MapControllers(); });
}
+
}
}
\ No newline at end of file
diff --git a/src/samples/server/Elsa.Samples.Server.Host/appsettings.Development.json b/src/samples/server/Elsa.Samples.Server.Host/appsettings.Development.json
index 99281afad..71e1f2132 100644
--- a/src/samples/server/Elsa.Samples.Server.Host/appsettings.Development.json
+++ b/src/samples/server/Elsa.Samples.Server.Host/appsettings.Development.json
@@ -6,5 +6,8 @@
"System": "Information",
"Microsoft": "Warning"
}
+ },
+ "Elsa": {
+ "Features": [ "Webhook", "Console" ]
}
}
diff --git a/test/shared/Elsa.Testing.Shared/Elsa.Testing.Shared.csproj b/test/shared/Elsa.Testing.Shared/Elsa.Testing.Shared.csproj
index aefda0a44..b13ba0ff5 100644
--- a/test/shared/Elsa.Testing.Shared/Elsa.Testing.Shared.csproj
+++ b/test/shared/Elsa.Testing.Shared/Elsa.Testing.Shared.csproj
@@ -1,4 +1,4 @@
-
+