diff --git a/Elsa.sln b/Elsa.sln
index 77a6f62af..69b533e49 100644
--- a/Elsa.sln
+++ b/Elsa.sln
@@ -64,8 +64,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa", "src\bundles\Elsa\El
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Formatting", "src\common\Elsa.Formatting\Elsa.Formatting.csproj", "{60CEE728-3187-481B-B6EA-10D5284D8B55}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Jobs.Abstractions", "src\common\Elsa.Jobs.Abstractions\Elsa.Jobs.Abstractions.csproj", "{2782C593-98CD-4B80-B595-8BAE066DCBC3}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.ServiceBus.Abstractions", "src\common\Elsa.ServiceBus.Abstractions\Elsa.ServiceBus.Abstractions.csproj", "{448FCDE6-DE44-4E44-A1CC-B9AA51471121}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Liquid", "src\modules\Elsa.Liquid\Elsa.Liquid.csproj", "{8E5BD3D9-3529-48BC-B741-CFB7A69DB233}"
@@ -118,7 +116,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Api.Common", "src\comm
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Tokens.Api", "src\modules\Elsa.Tokens.Api\Elsa.Tokens.Api.csproj", "{30B49E42-AE61-4F7C-981F-923F07BB3986}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Activities.Jobs", "src\modules\Elsa.Activities.Jobs\Elsa.Activities.Jobs.csproj", "{81A2AE6B-3D0C-4A4A-A80B-7A661FBC8117}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Jobs.Activities", "src\modules\Elsa.Jobs.Activities\Elsa.Jobs.Activities.csproj", "{81A2AE6B-3D0C-4A4A-A80B-7A661FBC8117}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Jobs", "src\modules\Elsa.Jobs\Elsa.Jobs.csproj", "{CF1938A0-BD10-4AA1-9ABC-6D02303A9D53}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Common", "src\modules\Elsa.Common\Elsa.Common.csproj", "{D229105F-6879-4452-9189-75DE060C0F4C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -206,10 +208,6 @@ Global
{60CEE728-3187-481B-B6EA-10D5284D8B55}.Debug|Any CPU.Build.0 = Debug|Any CPU
{60CEE728-3187-481B-B6EA-10D5284D8B55}.Release|Any CPU.ActiveCfg = Release|Any CPU
{60CEE728-3187-481B-B6EA-10D5284D8B55}.Release|Any CPU.Build.0 = Release|Any CPU
- {2782C593-98CD-4B80-B595-8BAE066DCBC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {2782C593-98CD-4B80-B595-8BAE066DCBC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {2782C593-98CD-4B80-B595-8BAE066DCBC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {2782C593-98CD-4B80-B595-8BAE066DCBC3}.Release|Any CPU.Build.0 = Release|Any CPU
{448FCDE6-DE44-4E44-A1CC-B9AA51471121}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{448FCDE6-DE44-4E44-A1CC-B9AA51471121}.Debug|Any CPU.Build.0 = Debug|Any CPU
{448FCDE6-DE44-4E44-A1CC-B9AA51471121}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -318,6 +316,14 @@ Global
{81A2AE6B-3D0C-4A4A-A80B-7A661FBC8117}.Debug|Any CPU.Build.0 = Debug|Any CPU
{81A2AE6B-3D0C-4A4A-A80B-7A661FBC8117}.Release|Any CPU.ActiveCfg = Release|Any CPU
{81A2AE6B-3D0C-4A4A-A80B-7A661FBC8117}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CF1938A0-BD10-4AA1-9ABC-6D02303A9D53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CF1938A0-BD10-4AA1-9ABC-6D02303A9D53}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CF1938A0-BD10-4AA1-9ABC-6D02303A9D53}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CF1938A0-BD10-4AA1-9ABC-6D02303A9D53}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D229105F-6879-4452-9189-75DE060C0F4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D229105F-6879-4452-9189-75DE060C0F4C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D229105F-6879-4452-9189-75DE060C0F4C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D229105F-6879-4452-9189-75DE060C0F4C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{155227F0-A33B-40AA-A4B4-06F813EB921B} = {61017E64-6D00-49CB-9E81-5002DC8F7D5F}
@@ -335,7 +341,6 @@ Global
{177F4FF3-4618-4CB1-BA93-8B024BC64CD8} = {56C2FFB8-EA54-45B5-A095-4A78142EB4B5}
{F06B9573-DF68-4606-866C-A7546A10A05A} = {61017E64-6D00-49CB-9E81-5002DC8F7D5F}
{60CEE728-3187-481B-B6EA-10D5284D8B55} = {C6658DE0-2B2F-47F0-BB61-2CA66D435C09}
- {2782C593-98CD-4B80-B595-8BAE066DCBC3} = {C6658DE0-2B2F-47F0-BB61-2CA66D435C09}
{448FCDE6-DE44-4E44-A1CC-B9AA51471121} = {C6658DE0-2B2F-47F0-BB61-2CA66D435C09}
{B2049499-D384-46DF-8837-F1180107DD54} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79}
{FC5D2CE9-FFB0-478D-8D54-E4109D1FD202} = {F06B9573-DF68-4606-866C-A7546A10A05A}
@@ -374,5 +379,7 @@ Global
{39CD855E-83B1-4A96-93F7-01608211EBE3} = {C6658DE0-2B2F-47F0-BB61-2CA66D435C09}
{30B49E42-AE61-4F7C-981F-923F07BB3986} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79}
{81A2AE6B-3D0C-4A4A-A80B-7A661FBC8117} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79}
+ {CF1938A0-BD10-4AA1-9ABC-6D02303A9D53} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79}
+ {D229105F-6879-4452-9189-75DE060C0F4C} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79}
EndGlobalSection
EndGlobal
diff --git a/src/bundles/Elsa.AllInOne.Web/Elsa.AllInOne.Web.csproj b/src/bundles/Elsa.AllInOne.Web/Elsa.AllInOne.Web.csproj
index 09ecd7742..34ab90a19 100644
--- a/src/bundles/Elsa.AllInOne.Web/Elsa.AllInOne.Web.csproj
+++ b/src/bundles/Elsa.AllInOne.Web/Elsa.AllInOne.Web.csproj
@@ -10,10 +10,10 @@
-
+
diff --git a/src/bundles/Elsa.AllInOne.Web/Program.cs b/src/bundles/Elsa.AllInOne.Web/Program.cs
index 8e415f7ea..2c093c996 100644
--- a/src/bundles/Elsa.AllInOne.Web/Program.cs
+++ b/src/bundles/Elsa.AllInOne.Web/Program.cs
@@ -1,17 +1,14 @@
-using System.Text.Json.Serialization;
using Elsa.Workflows.Api.Extensions;
using Elsa.AspNetCore.Extensions;
using Elsa.Extensions;
using Elsa.Jobs.Extensions;
-using Elsa.Hangfire.Implementations;
using Elsa.Http;
using Elsa.Http.Extensions;
using Elsa.JavaScript.Activities;
using Elsa.JavaScript.Extensions;
-using Elsa.Quartz.Implementations;
using Elsa.Scheduling.Activities;
-using Elsa.Scheduling.Extensions;
using Elsa.Liquid.Extensions;
+using Elsa.Scheduling.Extensions;
using Elsa.Workflows.Core;
using Elsa.Workflows.Core.Activities;
using Elsa.Workflows.Core.Activities.Flowchart.Activities;
@@ -43,6 +40,8 @@ services
.AddActivity()
.AddActivity()
)
+ .UseJobs()
+ .UseScheduling()
.UseJavaScript()
.UseLiquid()
.UseHttp()
@@ -50,10 +49,6 @@ services
.UseMvc()
);
-services
- .AddJobServices(new QuartzJobSchedulerProvider(), new HangfireJobQueueProvider())
- .AddSchedulingServices();
-
// Register serialization configurator for configuring what types to allow to be serialized.
services.AddSingleton();
services.AddSingleton();
diff --git a/src/bundles/Elsa.WorkflowServer.Web/Elsa.WorkflowServer.Web.csproj b/src/bundles/Elsa.WorkflowServer.Web/Elsa.WorkflowServer.Web.csproj
index a4b003b89..576b16841 100644
--- a/src/bundles/Elsa.WorkflowServer.Web/Elsa.WorkflowServer.Web.csproj
+++ b/src/bundles/Elsa.WorkflowServer.Web/Elsa.WorkflowServer.Web.csproj
@@ -7,7 +7,7 @@
-
+
diff --git a/src/bundles/Elsa.WorkflowServer.Web/Jobs/IndexBlockchainJob.cs b/src/bundles/Elsa.WorkflowServer.Web/Jobs/IndexBlockchainJob.cs
index 1268626be..be996b30a 100644
--- a/src/bundles/Elsa.WorkflowServer.Web/Jobs/IndexBlockchainJob.cs
+++ b/src/bundles/Elsa.WorkflowServer.Web/Jobs/IndexBlockchainJob.cs
@@ -1,5 +1,5 @@
-using Elsa.Activities.Jobs.Features;
using Elsa.Jobs.Abstractions;
+using Elsa.Jobs.Activities.Features;
using Elsa.Jobs.Models;
using Elsa.Jobs.Services;
@@ -7,7 +7,7 @@ namespace Elsa.WorkflowServer.Web.Jobs;
///
/// Jobs can be scheduled manually using ,
-/// but when enabling the , these jobs become available as activities too.
+/// but when enabling the , these jobs become available as activities too.
///
public class IndexBlockchainJob : Job
{
diff --git a/src/bundles/Elsa.WorkflowServer.Web/Program.cs b/src/bundles/Elsa.WorkflowServer.Web/Program.cs
index 919236969..b86170ff1 100644
--- a/src/bundles/Elsa.WorkflowServer.Web/Program.cs
+++ b/src/bundles/Elsa.WorkflowServer.Web/Program.cs
@@ -1,8 +1,5 @@
using System.Text.Json;
using System.Text.Json.Serialization;
-using Elsa.Activities.Jobs.Features;
-using Elsa.Activities.Jobs.Implementations;
-using Elsa.Activities.Jobs.Services;
using Elsa.ActivityDefinitions.EntityFrameworkCore.Extensions;
using Elsa.ActivityDefinitions.EntityFrameworkCore.Sqlite;
using Elsa.Api.Common;
@@ -11,18 +8,17 @@ using Elsa.Api.Common.Options;
using Elsa.AspNetCore.Extensions;
using Elsa.Extensions;
using Elsa.Features.Extensions;
-using Elsa.Hangfire.Implementations;
using Elsa.Http;
using Elsa.Http.Extensions;
using Elsa.JavaScript.Activities;
using Elsa.JavaScript.Extensions;
-using Elsa.Jobs.Extensions;
+using Elsa.Jobs.Activities.Extensions;
+using Elsa.Jobs.Activities.Implementations;
+using Elsa.Jobs.Activities.Services;
using Elsa.Labels.EntityFrameworkCore.Extensions;
using Elsa.Labels.EntityFrameworkCore.Sqlite;
using Elsa.Labels.Extensions;
using Elsa.Liquid.Extensions;
-using Elsa.Quartz.Implementations;
-using Elsa.Scheduling.Extensions;
using Elsa.WorkflowContexts.Extensions;
using Elsa.Workflows.Api.Extensions;
using Elsa.Workflows.Core.Activities;
@@ -35,7 +31,6 @@ using Elsa.Workflows.Persistence.EntityFrameworkCore.Extensions;
using Elsa.Workflows.Persistence.EntityFrameworkCore.Sqlite;
using Elsa.Workflows.Persistence.Extensions;
using Elsa.Workflows.Runtime.Extensions;
-using Elsa.WorkflowServer.Web;
using Elsa.WorkflowServer.Web.Implementations;
using Elsa.WorkflowServer.Web.Jobs;
using FastEndpoints;
@@ -80,7 +75,7 @@ services
feature.CredentialsValidator = sp => sp.GetRequiredService();
feature.AccessTokenIssuer = sp => sp.GetRequiredService();
})
- .Use()
+ .UseJobActivities()
.UseWorkflowPersistence(p => p.UseEntityFrameworkCore(ef => ef.UseSqlite()))
.UseWorkflowApiEndpoints()
.UseJavaScript()
@@ -91,11 +86,6 @@ services
.UseMvc()
);
-services
- .AddJobServices(new QuartzJobSchedulerProvider(), new HangfireJobQueueProvider())
- .AddSchedulingServices()
- ;
-
services.AddFastEndpoints();
services.AddAuthenticationJWTBearer(accessTokenOptions.SigningKey);
services.AddHealthChecks();
diff --git a/src/common/Elsa.Features/Implementations/Module.cs b/src/common/Elsa.Features/Implementations/Module.cs
index 9faf8ff41..c2819fb8d 100644
--- a/src/common/Elsa.Features/Implementations/Module.cs
+++ b/src/common/Elsa.Features/Implementations/Module.cs
@@ -11,7 +11,7 @@ public class Module : IModule
{
private record HostedServiceDescriptor(int Order, Type HostedServiceType);
- private readonly ISet _configurators = new HashSet();
+ private readonly ISet _features = new HashSet();
private readonly ICollection _hostedServiceDescriptors = new List();
public Module(IServiceCollection services)
@@ -25,10 +25,10 @@ public class Module : IModule
public T Configure(Func factory, Action? configure = default) where T : class, IFeature
{
- if (_configurators.FirstOrDefault(x => x is T) is not T configurator)
+ if (_features.FirstOrDefault(x => x is T) is not T configurator)
{
configurator = factory(this);
- _configurators.Add(configurator);
+ _features.Add(configurator);
}
configure?.Invoke(configurator);
@@ -45,18 +45,18 @@ public class Module : IModule
{
ResolveDependencies();
- foreach (var configurator in _configurators)
+ foreach (var feature in _features)
{
- configurator.Configure();
- configurator.ConfigureHostedServices();
+ feature.Configure();
+ feature.ConfigureHostedServices();
}
foreach (var hostedServiceDescriptor in _hostedServiceDescriptors.OrderBy(x => x.Order))
Services.TryAddEnumerable(ServiceDescriptor.Singleton(typeof(IHostedService), hostedServiceDescriptor.HostedServiceType));
- foreach (var configurator in _configurators)
+ foreach (var feature in _features)
{
- configurator.Apply();
+ feature.Apply();
}
}
@@ -64,7 +64,7 @@ public class Module : IModule
{
var resolvedDependencyTypes = new HashSet();
- foreach (var configurator in _configurators.ToList())
+ foreach (var configurator in _features.ToList())
ResolveDependencies(configurator, resolvedDependencyTypes);
}
@@ -83,13 +83,13 @@ public class Module : IModule
private IFeature AddConfigurator(Type type)
{
- var configurator = _configurators.FirstOrDefault(x => x.GetType() == type);
+ var configurator = _features.FirstOrDefault(x => x.GetType() == type);
if (configurator != null)
return configurator;
configurator = (IFeature)Activator.CreateInstance(type, this)!;
- _configurators.Add(configurator);
+ _features.Add(configurator);
return configurator;
}
}
\ No newline at end of file
diff --git a/src/common/Elsa.Jobs.Abstractions/AssemblyInfo.cs b/src/common/Elsa.Jobs.Abstractions/AssemblyInfo.cs
deleted file mode 100644
index e46bb2692..000000000
--- a/src/common/Elsa.Jobs.Abstractions/AssemblyInfo.cs
+++ /dev/null
@@ -1,2 +0,0 @@
-using System;
-[assembly: CLSCompliant(true)]
\ No newline at end of file
diff --git a/src/common/Elsa.Jobs.Abstractions/Extensions/DependencyInjectionExtensions.cs b/src/common/Elsa.Jobs.Abstractions/Extensions/DependencyInjectionExtensions.cs
deleted file mode 100644
index d27811ffc..000000000
--- a/src/common/Elsa.Jobs.Abstractions/Extensions/DependencyInjectionExtensions.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using Elsa.Jobs.Implementations;
-using Elsa.Jobs.Services;
-using Microsoft.Extensions.DependencyInjection;
-
-namespace Elsa.Jobs.Extensions;
-
-public static class DependencyInjectionExtensions
-{
- public static IServiceCollection AddJobServices(this IServiceCollection services, IJobSchedulerProvider schedulerProvider, IJobQueueProvider queueProvider)
- {
- services
- .AddSingleton()
- .AddSingleton()
- .AddSingleton();
-
- schedulerProvider.ConfigureServices(services);
- queueProvider.ConfigureServices(services);
- return services;
- }
-}
\ No newline at end of file
diff --git a/src/common/Elsa.Jobs.Abstractions/Services/IJobQueueProvider.cs b/src/common/Elsa.Jobs.Abstractions/Services/IJobQueueProvider.cs
deleted file mode 100644
index 1716dbd1c..000000000
--- a/src/common/Elsa.Jobs.Abstractions/Services/IJobQueueProvider.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-
-namespace Elsa.Jobs.Services;
-
-public interface IJobQueueProvider
-{
- void ConfigureServices(IServiceCollection services);
-}
\ No newline at end of file
diff --git a/src/common/Elsa.Jobs.Abstractions/Services/IJobSchedulerProvider.cs b/src/common/Elsa.Jobs.Abstractions/Services/IJobSchedulerProvider.cs
deleted file mode 100644
index ef9a58d42..000000000
--- a/src/common/Elsa.Jobs.Abstractions/Services/IJobSchedulerProvider.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-
-namespace Elsa.Jobs.Services;
-
-public interface IJobSchedulerProvider
-{
- void ConfigureServices(IServiceCollection services);
-}
\ No newline at end of file
diff --git a/src/common/Elsa.ServiceBus.Abstractions/Services/IServiceBusProvider.cs b/src/common/Elsa.ServiceBus.Abstractions/Services/IServiceBusProvider.cs
deleted file mode 100644
index ef8d9e409..000000000
--- a/src/common/Elsa.ServiceBus.Abstractions/Services/IServiceBusProvider.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-
-namespace Elsa.ServiceBus.Abstractions.Services;
-
-public interface IServiceBusProvider
-{
- void ConfigureServices(IServiceCollection services);
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.ActivityDefinitions/Features/ActivityDefinitionsFeature.cs b/src/modules/Elsa.ActivityDefinitions/Features/ActivityDefinitionsFeature.cs
index 41717ae06..43f092269 100644
--- a/src/modules/Elsa.ActivityDefinitions/Features/ActivityDefinitionsFeature.cs
+++ b/src/modules/Elsa.ActivityDefinitions/Features/ActivityDefinitionsFeature.cs
@@ -1,6 +1,7 @@
using Elsa.ActivityDefinitions.Entities;
using Elsa.ActivityDefinitions.Implementations;
using Elsa.ActivityDefinitions.Services;
+using Elsa.Common.Features;
using Elsa.Features.Abstractions;
using Elsa.Features.Attributes;
using Elsa.Features.Services;
@@ -14,6 +15,7 @@ using Microsoft.Extensions.DependencyInjection;
namespace Elsa.ActivityDefinitions.Features;
[DependsOn(typeof(MediatorFeature))]
+[DependsOn(typeof(SystemClockFeature))]
public class ActivityDefinitionsFeature : FeatureBase
{
public ActivityDefinitionsFeature(IModule module) : base(module)
diff --git a/src/modules/Elsa.ActivityDefinitions/Implementations/ActivityDefinitionPublisher.cs b/src/modules/Elsa.ActivityDefinitions/Implementations/ActivityDefinitionPublisher.cs
index 0d357458a..61e2f3b07 100644
--- a/src/modules/Elsa.ActivityDefinitions/Implementations/ActivityDefinitionPublisher.cs
+++ b/src/modules/Elsa.ActivityDefinitions/Implementations/ActivityDefinitionPublisher.cs
@@ -2,6 +2,7 @@ using System.Text.Json;
using Elsa.ActivityDefinitions.Entities;
using Elsa.ActivityDefinitions.Notifications;
using Elsa.ActivityDefinitions.Services;
+using Elsa.Common.Services;
using Elsa.Mediator.Services;
using Elsa.Persistence.Common.Models;
using Elsa.Workflows.Core.Activities.Flowchart.Activities;
diff --git a/src/modules/Elsa.AzureServiceBus/Implementations/Worker.cs b/src/modules/Elsa.AzureServiceBus/Implementations/Worker.cs
index 2afa49abc..338d81b90 100644
--- a/src/modules/Elsa.AzureServiceBus/Implementations/Worker.cs
+++ b/src/modules/Elsa.AzureServiceBus/Implementations/Worker.cs
@@ -3,7 +3,6 @@ using Elsa.AzureServiceBus.Activities;
using Elsa.AzureServiceBus.Models;
using Elsa.Workflows.Core.Helpers;
using Elsa.Workflows.Core.Services;
-using Elsa.Workflows.Runtime.Models;
using Elsa.Workflows.Runtime.Services;
using Microsoft.Extensions.Logging;
diff --git a/src/modules/Elsa.Common/Elsa.Common.csproj b/src/modules/Elsa.Common/Elsa.Common.csproj
new file mode 100644
index 000000000..5465086a8
--- /dev/null
+++ b/src/modules/Elsa.Common/Elsa.Common.csproj
@@ -0,0 +1,13 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/src/modules/Elsa.Common/Features/SystemClockFeature.cs b/src/modules/Elsa.Common/Features/SystemClockFeature.cs
new file mode 100644
index 000000000..addea2d13
--- /dev/null
+++ b/src/modules/Elsa.Common/Features/SystemClockFeature.cs
@@ -0,0 +1,19 @@
+using Elsa.Common.Implementations;
+using Elsa.Common.Services;
+using Elsa.Features.Abstractions;
+using Elsa.Features.Services;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Elsa.Common.Features;
+
+public class SystemClockFeature : FeatureBase
+{
+ public SystemClockFeature(IModule module) : base(module)
+ {
+ }
+
+ public override void Apply()
+ {
+ Services.AddSingleton();
+ }
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Workflows.Core/Implementations/SystemClock.cs b/src/modules/Elsa.Common/Implementations/SystemClock.cs
similarity index 55%
rename from src/modules/Elsa.Workflows.Core/Implementations/SystemClock.cs
rename to src/modules/Elsa.Common/Implementations/SystemClock.cs
index b61f29b6e..b8a731857 100644
--- a/src/modules/Elsa.Workflows.Core/Implementations/SystemClock.cs
+++ b/src/modules/Elsa.Common/Implementations/SystemClock.cs
@@ -1,6 +1,6 @@
-using Elsa.Workflows.Core.Services;
+using Elsa.Common.Services;
-namespace Elsa.Workflows.Core.Implementations;
+namespace Elsa.Common.Implementations;
public class SystemClock : ISystemClock
{
diff --git a/src/modules/Elsa.Workflows.Core/Services/ISystemClock.cs b/src/modules/Elsa.Common/Services/ISystemClock.cs
similarity index 63%
rename from src/modules/Elsa.Workflows.Core/Services/ISystemClock.cs
rename to src/modules/Elsa.Common/Services/ISystemClock.cs
index 4c5a2a900..d674c8857 100644
--- a/src/modules/Elsa.Workflows.Core/Services/ISystemClock.cs
+++ b/src/modules/Elsa.Common/Services/ISystemClock.cs
@@ -1,4 +1,4 @@
-namespace Elsa.Workflows.Core.Services;
+namespace Elsa.Common.Services;
public interface ISystemClock
{
diff --git a/src/modules/Elsa.Hangfire/Elsa.Hangfire.csproj b/src/modules/Elsa.Hangfire/Elsa.Hangfire.csproj
index 2d2ee6b2d..baeb84fe0 100644
--- a/src/modules/Elsa.Hangfire/Elsa.Hangfire.csproj
+++ b/src/modules/Elsa.Hangfire/Elsa.Hangfire.csproj
@@ -12,7 +12,7 @@
-
+
diff --git a/src/modules/Elsa.Hangfire/Features/HangfireFeature.cs b/src/modules/Elsa.Hangfire/Features/HangfireFeature.cs
new file mode 100644
index 000000000..e60476173
--- /dev/null
+++ b/src/modules/Elsa.Hangfire/Features/HangfireFeature.cs
@@ -0,0 +1,44 @@
+using Elsa.Features.Abstractions;
+using Elsa.Features.Services;
+using Hangfire;
+using Hangfire.MemoryStorage;
+using Hangfire.SqlServer;
+using Newtonsoft.Json;
+
+namespace Elsa.Hangfire.Features;
+
+public class HangfireFeature : FeatureBase
+{
+ public HangfireFeature(IModule module) : base(module)
+ {
+ }
+
+ public bool UseSqlServerStorage { get; set; }
+ public SqlServerStorageOptions? SqlServerStorageOptions { get; set; }
+ public string? SqlServerConnectionString { get; set; }
+ public Action? ConfigureBackgroundServerOptions { get; set; }
+
+ public override void Configure()
+ {
+ Services.AddHangfire(configuration =>
+ {
+ configuration.UseSimpleAssemblyNameTypeSerializer();
+ configuration.UseRecommendedSerializerSettings(json => json.TypeNameHandling = TypeNameHandling.Objects);
+
+ if (UseSqlServerStorage)
+ {
+ var storageOptions = SqlServerStorageOptions ?? new SqlServerStorageOptions();
+ configuration.UseSqlServerStorage(SqlServerConnectionString, storageOptions);
+ }
+ else
+ {
+ configuration.UseMemoryStorage();
+ }
+ });
+
+ if (UseSqlServerStorage)
+ Services.AddHangfireServer((_, options) => ConfigureBackgroundServerOptions?.Invoke(options), new SqlServerStorage(SqlServerConnectionString));
+ else
+ Services.AddHangfireServer(options => { ConfigureBackgroundServerOptions?.Invoke(options); });
+ }
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Hangfire/Features/HangfireJobsFeature.cs b/src/modules/Elsa.Hangfire/Features/HangfireJobsFeature.cs
new file mode 100644
index 000000000..922b20a00
--- /dev/null
+++ b/src/modules/Elsa.Hangfire/Features/HangfireJobsFeature.cs
@@ -0,0 +1,23 @@
+using Elsa.Features.Abstractions;
+using Elsa.Features.Attributes;
+using Elsa.Features.Extensions;
+using Elsa.Features.Services;
+using Elsa.Hangfire.Implementations;
+using Elsa.Jobs.Features;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Elsa.Hangfire.Features;
+
+[DependsOn(typeof(JobsFeature))]
+[DependsOn(typeof(HangfireFeature))]
+public class HangfireJobsFeature : FeatureBase
+{
+ public HangfireJobsFeature(IModule module) : base(module)
+ {
+ }
+
+ public override void Configure()
+ {
+ Module.Use(f => f.JobQueueFactory = ActivatorUtilities.GetServiceOrCreateInstance);
+ }
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Hangfire/Implementations/HangfireJobQueue.cs b/src/modules/Elsa.Hangfire/Implementations/HangfireJobQueue.cs
index c8e85d27b..a7547ccf9 100644
--- a/src/modules/Elsa.Hangfire/Implementations/HangfireJobQueue.cs
+++ b/src/modules/Elsa.Hangfire/Implementations/HangfireJobQueue.cs
@@ -1,7 +1,6 @@
using Elsa.Hangfire.Jobs;
using Elsa.Jobs.Services;
using Hangfire;
-using Hangfire.Server;
using Hangfire.States;
using HangfireJob = Hangfire.Common.Job;
@@ -16,11 +15,11 @@ public class HangfireJobQueue : IJobQueue
_backgroundJobClient = backgroundJobClient;
}
- public Task SubmitJobAsync(IJob job, string? queueName = default, CancellationToken cancellationToken = default)
+ public Task SubmitJobAsync(IJob job, string? queueName = default, CancellationToken cancellationToken = default)
{
var hangfireJob = HangfireJob.FromExpression(x => x.RunAsync(job, CancellationToken.None));
- var jobId = _backgroundJobClient.Create(hangfireJob, new EnqueuedState(queueName ?? "default"));
+ _backgroundJobClient.Create(hangfireJob, new EnqueuedState(queueName ?? "default"));
- return Task.FromResult(jobId);
+ return Task.CompletedTask;
}
}
\ No newline at end of file
diff --git a/src/modules/Elsa.Hangfire/Implementations/HangfireJobQueueProvider.cs b/src/modules/Elsa.Hangfire/Implementations/HangfireJobQueueProvider.cs
deleted file mode 100644
index 235bce994..000000000
--- a/src/modules/Elsa.Hangfire/Implementations/HangfireJobQueueProvider.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-using Elsa.Jobs.Services;
-using Hangfire;
-using Hangfire.MemoryStorage;
-using Hangfire.SqlServer;
-using Microsoft.Extensions.DependencyInjection;
-using Newtonsoft.Json;
-
-namespace Elsa.Hangfire.Implementations;
-
-public class HangfireJobQueueProvider : IJobQueueProvider
-{
- public HangfireJobQueueProvider(bool registerHangfire = true)
- {
- RegisterHangfire = registerHangfire;
- }
-
- public HangfireJobQueueProvider(string sqlServerConnectionString)
- {
- SqlServerConnectionString = sqlServerConnectionString;
- UseSqlServerStorage = true;
- RegisterHangfire = true;
- }
-
- public bool RegisterHangfire { get; set; }
- public bool UseSqlServerStorage { get; set; }
- public string? SqlServerConnectionString { get; set; }
- public SqlServerStorageOptions? SqlServerStorageOptions { get; set; }
- public Action? ConfigureBackgroundServerOptions { get; set; }
-
- public void ConfigureServices(IServiceCollection services)
- {
- if (RegisterHangfire)
- {
- services.AddHangfire(configuration =>
- {
- configuration.UseSimpleAssemblyNameTypeSerializer();
- configuration.UseRecommendedSerializerSettings(json => json.TypeNameHandling = TypeNameHandling.Objects);
-
- if (UseSqlServerStorage)
- {
- var storageOptions = SqlServerStorageOptions ?? new SqlServerStorageOptions();
- configuration.UseSqlServerStorage(SqlServerConnectionString, storageOptions);
- }
- else
- {
- configuration.UseMemoryStorage();
- }
- });
-
- if (UseSqlServerStorage)
- services.AddHangfireServer((_, options) => ConfigureBackgroundServerOptions?.Invoke(options), new SqlServerStorage(SqlServerConnectionString));
- else
- services.AddHangfireServer(options =>
- {
- ConfigureBackgroundServerOptions?.Invoke(options);
- });
- }
-
- services.AddSingleton();
- }
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Hangfire/Jobs/RunElsaJob.cs b/src/modules/Elsa.Hangfire/Jobs/RunElsaJob.cs
index 8ca85b084..544d4af44 100644
--- a/src/modules/Elsa.Hangfire/Jobs/RunElsaJob.cs
+++ b/src/modules/Elsa.Hangfire/Jobs/RunElsaJob.cs
@@ -1,5 +1,4 @@
using Elsa.Jobs.Services;
-using Hangfire.Server;
namespace Elsa.Hangfire.Jobs;
diff --git a/src/modules/Elsa.Activities.Jobs/Activities/JobActivity.cs b/src/modules/Elsa.Jobs.Activities/Activities/JobActivity.cs
similarity index 84%
rename from src/modules/Elsa.Activities.Jobs/Activities/JobActivity.cs
rename to src/modules/Elsa.Jobs.Activities/Activities/JobActivity.cs
index bd3b74546..20bfc3b2b 100644
--- a/src/modules/Elsa.Activities.Jobs/Activities/JobActivity.cs
+++ b/src/modules/Elsa.Jobs.Activities/Activities/JobActivity.cs
@@ -1,11 +1,12 @@
-using Elsa.Activities.Jobs.Models;
+using Elsa.Jobs.Activities.Models;
using Elsa.Jobs.Services;
using Elsa.Workflows.Core.Models;
+// ReSharper disable once CheckNamespace
namespace Elsa.Activities.Jobs.Activities;
///
-/// Executes a given job, suspending execution of the workflow until the job finishes.
+/// Executes a job of a given type, suspending execution of the workflow until the job finishes.
///
public class JobActivity : ActivityBase
{
diff --git a/src/modules/Elsa.Activities.Jobs/Attributes/JobAttribute.cs b/src/modules/Elsa.Jobs.Activities/Attributes/JobAttribute.cs
similarity index 95%
rename from src/modules/Elsa.Activities.Jobs/Attributes/JobAttribute.cs
rename to src/modules/Elsa.Jobs.Activities/Attributes/JobAttribute.cs
index 4ebb6554e..3e6d2e239 100644
--- a/src/modules/Elsa.Activities.Jobs/Attributes/JobAttribute.cs
+++ b/src/modules/Elsa.Jobs.Activities/Attributes/JobAttribute.cs
@@ -1,4 +1,4 @@
-namespace Elsa.Activities.Jobs.Attributes;
+namespace Elsa.Jobs.Activities.Attributes;
[AttributeUsage(AttributeTargets.Class)]
public class JobAttribute : Attribute
diff --git a/src/modules/Elsa.Activities.Jobs/Elsa.Activities.Jobs.csproj b/src/modules/Elsa.Jobs.Activities/Elsa.Jobs.Activities.csproj
similarity index 75%
rename from src/modules/Elsa.Activities.Jobs/Elsa.Activities.Jobs.csproj
rename to src/modules/Elsa.Jobs.Activities/Elsa.Jobs.Activities.csproj
index 669c9b6b7..8576d04d7 100644
--- a/src/modules/Elsa.Activities.Jobs/Elsa.Activities.Jobs.csproj
+++ b/src/modules/Elsa.Jobs.Activities/Elsa.Jobs.Activities.csproj
@@ -7,14 +7,10 @@
-
+
-
-
-
-
diff --git a/src/modules/Elsa.Jobs.Activities/Extensions/ModuleExtensions.cs b/src/modules/Elsa.Jobs.Activities/Extensions/ModuleExtensions.cs
new file mode 100644
index 000000000..e90ad2855
--- /dev/null
+++ b/src/modules/Elsa.Jobs.Activities/Extensions/ModuleExtensions.cs
@@ -0,0 +1,13 @@
+using Elsa.Features.Services;
+using Elsa.Jobs.Activities.Features;
+
+namespace Elsa.Jobs.Activities.Extensions;
+
+public static class ModuleExtensions
+{
+ public static IModule UseJobActivities(this IModule module, Action? configure = default )
+ {
+ module.Configure(configure);
+ return module;
+ }
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Activities.Jobs/Features/JobsFeature.cs b/src/modules/Elsa.Jobs.Activities/Features/JobActivitiesFeature.cs
similarity index 65%
rename from src/modules/Elsa.Activities.Jobs/Features/JobsFeature.cs
rename to src/modules/Elsa.Jobs.Activities/Features/JobActivitiesFeature.cs
index 02af3d692..bf31df63b 100644
--- a/src/modules/Elsa.Activities.Jobs/Features/JobsFeature.cs
+++ b/src/modules/Elsa.Jobs.Activities/Features/JobActivitiesFeature.cs
@@ -1,19 +1,21 @@
-using Elsa.Activities.Jobs.Implementations;
-using Elsa.Activities.Jobs.Services;
using Elsa.Features.Abstractions;
using Elsa.Features.Attributes;
using Elsa.Features.Services;
+using Elsa.Jobs.Activities.Implementations;
+using Elsa.Jobs.Activities.Services;
+using Elsa.Jobs.Features;
using Elsa.Mediator.Extensions;
using Elsa.Mediator.Features;
using Elsa.Workflows.Management.Services;
using Microsoft.Extensions.DependencyInjection;
-namespace Elsa.Activities.Jobs.Features;
+namespace Elsa.Jobs.Activities.Features;
[DependsOn(typeof(MediatorFeature))]
-public class JobsFeature : FeatureBase
+[DependsOn(typeof(JobsFeature))]
+public class JobActivitiesFeature : FeatureBase
{
- public JobsFeature(IModule module) : base(module)
+ public JobActivitiesFeature(IModule module) : base(module)
{
}
diff --git a/src/modules/Elsa.Activities.Jobs/Handlers/JobExecutedHandler.cs b/src/modules/Elsa.Jobs.Activities/Handlers/JobExecutedHandler.cs
similarity index 87%
rename from src/modules/Elsa.Activities.Jobs/Handlers/JobExecutedHandler.cs
rename to src/modules/Elsa.Jobs.Activities/Handlers/JobExecutedHandler.cs
index 25b191929..0ea592a71 100644
--- a/src/modules/Elsa.Activities.Jobs/Handlers/JobExecutedHandler.cs
+++ b/src/modules/Elsa.Jobs.Activities/Handlers/JobExecutedHandler.cs
@@ -1,10 +1,10 @@
-using Elsa.Activities.Jobs.Helpers;
-using Elsa.Activities.Jobs.Models;
+using Elsa.Jobs.Activities.Helpers;
+using Elsa.Jobs.Activities.Models;
using Elsa.Jobs.Notifications;
using Elsa.Mediator.Services;
using Elsa.Workflows.Runtime.Services;
-namespace Elsa.Activities.Jobs.Handlers;
+namespace Elsa.Jobs.Activities.Handlers;
public class JobExecutedHandler : INotificationHandler
{
diff --git a/src/modules/Elsa.Activities.Jobs/Helpers/JobTypeNameHelper.cs b/src/modules/Elsa.Jobs.Activities/Helpers/JobTypeNameHelper.cs
similarity index 87%
rename from src/modules/Elsa.Activities.Jobs/Helpers/JobTypeNameHelper.cs
rename to src/modules/Elsa.Jobs.Activities/Helpers/JobTypeNameHelper.cs
index ba065eb6c..304502b67 100644
--- a/src/modules/Elsa.Activities.Jobs/Helpers/JobTypeNameHelper.cs
+++ b/src/modules/Elsa.Jobs.Activities/Helpers/JobTypeNameHelper.cs
@@ -1,10 +1,8 @@
using System.Reflection;
-using Elsa.Activities.Jobs.Attributes;
+using Elsa.Jobs.Activities.Attributes;
using Elsa.Jobs.Services;
-using Elsa.Workflows.Core.Attributes;
-using Elsa.Workflows.Core.Services;
-namespace Elsa.Activities.Jobs.Helpers;
+namespace Elsa.Jobs.Activities.Helpers;
public static class JobTypeNameHelper
{
diff --git a/src/modules/Elsa.Activities.Jobs/Implementations/JobActivityProvider.cs b/src/modules/Elsa.Jobs.Activities/Implementations/JobActivityProvider.cs
similarity index 94%
rename from src/modules/Elsa.Activities.Jobs/Implementations/JobActivityProvider.cs
rename to src/modules/Elsa.Jobs.Activities/Implementations/JobActivityProvider.cs
index 066dab1bc..694256d60 100644
--- a/src/modules/Elsa.Activities.Jobs/Implementations/JobActivityProvider.cs
+++ b/src/modules/Elsa.Jobs.Activities/Implementations/JobActivityProvider.cs
@@ -1,9 +1,9 @@
using System.ComponentModel;
using System.Reflection;
using Elsa.Activities.Jobs.Activities;
-using Elsa.Activities.Jobs.Attributes;
-using Elsa.Activities.Jobs.Helpers;
-using Elsa.Activities.Jobs.Services;
+using Elsa.Jobs.Activities.Attributes;
+using Elsa.Jobs.Activities.Helpers;
+using Elsa.Jobs.Activities.Services;
using Elsa.Jobs.Services;
using Elsa.Workflows.Core.Helpers;
using Elsa.Workflows.Core.Models;
@@ -11,7 +11,7 @@ using Elsa.Workflows.Management.Extensions;
using Elsa.Workflows.Management.Services;
using Humanizer;
-namespace Elsa.Activities.Jobs.Implementations;
+namespace Elsa.Jobs.Activities.Implementations;
///
/// Provides activity descriptors based on registered implementations.
diff --git a/src/modules/Elsa.Activities.Jobs/Implementations/JobRegistry.cs b/src/modules/Elsa.Jobs.Activities/Implementations/JobRegistry.cs
similarity index 74%
rename from src/modules/Elsa.Activities.Jobs/Implementations/JobRegistry.cs
rename to src/modules/Elsa.Jobs.Activities/Implementations/JobRegistry.cs
index de068c8e7..8a21563e0 100644
--- a/src/modules/Elsa.Activities.Jobs/Implementations/JobRegistry.cs
+++ b/src/modules/Elsa.Jobs.Activities/Implementations/JobRegistry.cs
@@ -1,6 +1,6 @@
-using Elsa.Activities.Jobs.Services;
+using Elsa.Jobs.Activities.Services;
-namespace Elsa.Activities.Jobs.Implementations;
+namespace Elsa.Jobs.Activities.Implementations;
public class JobRegistry : IJobRegistry
{
diff --git a/src/modules/Elsa.Activities.Jobs/Models/EnqueuedJobPayload.cs b/src/modules/Elsa.Jobs.Activities/Models/EnqueuedJobPayload.cs
similarity index 87%
rename from src/modules/Elsa.Activities.Jobs/Models/EnqueuedJobPayload.cs
rename to src/modules/Elsa.Jobs.Activities/Models/EnqueuedJobPayload.cs
index 5d10a4b9a..8ca37cb5d 100644
--- a/src/modules/Elsa.Activities.Jobs/Models/EnqueuedJobPayload.cs
+++ b/src/modules/Elsa.Jobs.Activities/Models/EnqueuedJobPayload.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace Elsa.Activities.Jobs.Models;
+namespace Elsa.Jobs.Activities.Models;
public record EnqueuedJobPayload
{
diff --git a/src/modules/Elsa.Activities.Jobs/Services/IJobRegistry.cs b/src/modules/Elsa.Jobs.Activities/Services/IJobRegistry.cs
similarity index 79%
rename from src/modules/Elsa.Activities.Jobs/Services/IJobRegistry.cs
rename to src/modules/Elsa.Jobs.Activities/Services/IJobRegistry.cs
index 85db48071..a973291c6 100644
--- a/src/modules/Elsa.Activities.Jobs/Services/IJobRegistry.cs
+++ b/src/modules/Elsa.Jobs.Activities/Services/IJobRegistry.cs
@@ -1,4 +1,4 @@
-namespace Elsa.Activities.Jobs.Services;
+namespace Elsa.Jobs.Activities.Services;
///
/// Represents a registry of jobs.
diff --git a/src/common/Elsa.Jobs.Abstractions/Abstractions/Job.cs b/src/modules/Elsa.Jobs/Abstractions/Job.cs
similarity index 87%
rename from src/common/Elsa.Jobs.Abstractions/Abstractions/Job.cs
rename to src/modules/Elsa.Jobs/Abstractions/Job.cs
index df6230968..03cb214c8 100644
--- a/src/common/Elsa.Jobs.Abstractions/Abstractions/Job.cs
+++ b/src/modules/Elsa.Jobs/Abstractions/Job.cs
@@ -4,6 +4,9 @@ using Elsa.Jobs.Services;
namespace Elsa.Jobs.Abstractions;
+///
+/// A base class for job implementations.
+///
public abstract class Job : IJob
{
public string Id { get; set; } = default!;
diff --git a/src/common/Elsa.Jobs.Abstractions/Elsa.Jobs.Abstractions.csproj b/src/modules/Elsa.Jobs/Elsa.Jobs.csproj
similarity index 80%
rename from src/common/Elsa.Jobs.Abstractions/Elsa.Jobs.Abstractions.csproj
rename to src/modules/Elsa.Jobs/Elsa.Jobs.csproj
index af9c3eba4..6de17f7a7 100644
--- a/src/common/Elsa.Jobs.Abstractions/Elsa.Jobs.Abstractions.csproj
+++ b/src/modules/Elsa.Jobs/Elsa.Jobs.csproj
@@ -8,11 +8,13 @@
+
+
diff --git a/src/modules/Elsa.Jobs/Extensions/ModuleExtensions.cs b/src/modules/Elsa.Jobs/Extensions/ModuleExtensions.cs
new file mode 100644
index 000000000..0385f9807
--- /dev/null
+++ b/src/modules/Elsa.Jobs/Extensions/ModuleExtensions.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Threading.Channels;
+using Elsa.Features.Services;
+using Elsa.Jobs.Features;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Elsa.Jobs.Extensions;
+
+public static class ModuleExtensions
+{
+ public static IModule UseJobs(this IModule module, Action? configure = default )
+ {
+ module.Configure(configure);
+ return module;
+ }
+
+ public static IServiceCollection CreateChannel(this IServiceCollection services) =>
+ services
+ .AddSingleton(CreateChannel())
+ .AddSingleton(CreateChannelReader)
+ .AddSingleton(CreateChannelWriter);
+
+ private static Channel CreateChannel() => Channel.CreateUnbounded(new UnboundedChannelOptions());
+ private static ChannelReader CreateChannelReader(IServiceProvider serviceProvider) => serviceProvider.GetRequiredService>().Reader;
+ private static ChannelWriter CreateChannelWriter(IServiceProvider serviceProvider) => serviceProvider.GetRequiredService>().Writer;
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Jobs/Features/JobsFeature.cs b/src/modules/Elsa.Jobs/Features/JobsFeature.cs
new file mode 100644
index 000000000..ef9ed0c34
--- /dev/null
+++ b/src/modules/Elsa.Jobs/Features/JobsFeature.cs
@@ -0,0 +1,44 @@
+using System;
+using Elsa.Common.Features;
+using Elsa.Features.Abstractions;
+using Elsa.Features.Attributes;
+using Elsa.Features.Services;
+using Elsa.Jobs.Extensions;
+using Elsa.Jobs.HostedServices;
+using Elsa.Jobs.Implementations;
+using Elsa.Jobs.Services;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Elsa.Jobs.Features;
+
+[DependsOn(typeof(SystemClockFeature))]
+public class JobsFeature : FeatureBase
+{
+ public JobsFeature(IModule module) : base(module)
+ {
+ }
+
+ public Func JobQueueFactory { get; set; } = ActivatorUtilities.GetServiceOrCreateInstance;
+ public Func JobSchedulerFactory { get; set; } = ActivatorUtilities.GetServiceOrCreateInstance;
+
+ public override void Configure()
+ {
+ Services
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton();
+ }
+
+ public override void ConfigureHostedServices()
+ {
+ Services.AddHostedService();
+ }
+
+ public override void Apply()
+ {
+ Services
+ .AddSingleton(JobQueueFactory)
+ .AddSingleton(JobSchedulerFactory)
+ .CreateChannel();
+ }
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Jobs/HostedServices/JobQueueHostedService.cs b/src/modules/Elsa.Jobs/HostedServices/JobQueueHostedService.cs
new file mode 100644
index 000000000..2906c5c3d
--- /dev/null
+++ b/src/modules/Elsa.Jobs/HostedServices/JobQueueHostedService.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Threading;
+using System.Threading.Channels;
+using System.Threading.Tasks;
+using Elsa.Jobs.Services;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+
+namespace Elsa.Jobs.HostedServices;
+
+///
+/// Continuously reads from a channel to which jobs can be sent, executing each received job.
+///
+public class JobQueueHostedService : BackgroundService
+{
+ private readonly ChannelReader _channelReader;
+ private readonly IJobRunner _jobRunner;
+ private readonly ILogger _logger;
+
+ public JobQueueHostedService(ChannelReader channelReader, IJobRunner jobRunner, ILogger logger)
+ {
+ _channelReader = channelReader;
+ _jobRunner = jobRunner;
+ _logger = logger;
+ }
+
+ protected override async Task ExecuteAsync(CancellationToken cancellationToken)
+ {
+ await foreach (var job in _channelReader.ReadAllAsync(cancellationToken))
+ {
+ try
+ {
+ await _jobRunner.RunJobAsync(job, cancellationToken);
+ }
+ catch (Exception e)
+ {
+ _logger.LogError(e, "An unhandled exception occured while running a job");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/common/Elsa.Jobs.Abstractions/Implementations/JobFactory.cs b/src/modules/Elsa.Jobs/Implementations/JobFactory.cs
similarity index 83%
rename from src/common/Elsa.Jobs.Abstractions/Implementations/JobFactory.cs
rename to src/modules/Elsa.Jobs/Implementations/JobFactory.cs
index 555120ede..8338c3f5b 100644
--- a/src/common/Elsa.Jobs.Abstractions/Implementations/JobFactory.cs
+++ b/src/modules/Elsa.Jobs/Implementations/JobFactory.cs
@@ -1,6 +1,7 @@
using System;
+using Elsa.Jobs.Services;
-namespace Elsa.Jobs.Services;
+namespace Elsa.Jobs.Implementations;
public class JobFactory : IJobFactory
{
diff --git a/src/common/Elsa.Jobs.Abstractions/Implementations/JobRunner.cs b/src/modules/Elsa.Jobs/Implementations/JobRunner.cs
similarity index 100%
rename from src/common/Elsa.Jobs.Abstractions/Implementations/JobRunner.cs
rename to src/modules/Elsa.Jobs/Implementations/JobRunner.cs
diff --git a/src/common/Elsa.Jobs.Abstractions/Implementations/JobSerializer.cs b/src/modules/Elsa.Jobs/Implementations/JobSerializer.cs
similarity index 100%
rename from src/common/Elsa.Jobs.Abstractions/Implementations/JobSerializer.cs
rename to src/modules/Elsa.Jobs/Implementations/JobSerializer.cs
diff --git a/src/modules/Elsa.Jobs/Implementations/LocalJobQueue.cs b/src/modules/Elsa.Jobs/Implementations/LocalJobQueue.cs
new file mode 100644
index 000000000..7f3d63faf
--- /dev/null
+++ b/src/modules/Elsa.Jobs/Implementations/LocalJobQueue.cs
@@ -0,0 +1,24 @@
+using System.Threading;
+using System.Threading.Channels;
+using System.Threading.Tasks;
+using Elsa.Jobs.Services;
+
+namespace Elsa.Jobs.Implementations;
+
+///
+/// Represents a local, in-memory queue of jobs that will be processed in-process.
+///
+public class LocalJobQueue : IJobQueue
+{
+ private readonly ChannelWriter _channelWriter;
+
+ public LocalJobQueue(ChannelWriter channelWriter)
+ {
+ _channelWriter = channelWriter;
+ }
+
+ public async Task SubmitJobAsync(IJob job, string? queueName = default, CancellationToken cancellationToken = default)
+ {
+ await _channelWriter.WriteAsync(job, cancellationToken);
+ }
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Jobs/Implementations/LocalJobScheduler.cs b/src/modules/Elsa.Jobs/Implementations/LocalJobScheduler.cs
new file mode 100644
index 000000000..6e9ed857b
--- /dev/null
+++ b/src/modules/Elsa.Jobs/Implementations/LocalJobScheduler.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using Elsa.Common.Services;
+using Elsa.Jobs.ScheduledJobs;
+using Elsa.Jobs.Schedules;
+using Elsa.Jobs.Services;
+
+namespace Elsa.Jobs.Implementations;
+
+public class LocalJobScheduler : IJobScheduler
+{
+ private readonly ISystemClock _systemClock;
+ private readonly IJobRunner _jobRunner;
+ private readonly IDictionary _scheduledJobs = new Dictionary();
+
+ public LocalJobScheduler(ISystemClock systemClock, IJobRunner jobRunner)
+ {
+ _systemClock = systemClock;
+ _jobRunner = jobRunner;
+ }
+
+ public Task ScheduleAsync(IJob job, string name, ISchedule schedule, string[]? groupKeys = default, CancellationToken cancellationToken = default)
+ {
+ switch (schedule)
+ {
+ case CronSchedule cronSchedule:
+ {
+ var scheduledJob = new ScheduledCronJob(name, job, _systemClock, cronSchedule.CronExpression, _jobRunner, cancellationToken);
+ RegisterScheduledJob(scheduledJob);
+ break;
+ }
+ case RecurringSchedule recurringSchedule:
+ {
+ var scheduledJob = new ScheduledRecurringJob(name, job, _systemClock, recurringSchedule.StartAt, recurringSchedule.Interval, _jobRunner, cancellationToken);
+ RegisterScheduledJob(scheduledJob);
+ break;
+ }
+ case SpecificInstantSchedule specificInstantSchedule:
+ {
+ var scheduledJob = new ScheduledSpecificInstantJob(name, job, _systemClock, specificInstantSchedule.DateTime, _jobRunner, cancellationToken);
+ RegisterScheduledJob(scheduledJob);
+ break;
+ }
+ default:
+ throw new NotSupportedException($"Schedule of type {schedule.GetType()} is not supported.");
+ }
+
+ return Task.CompletedTask;
+ }
+
+ private void RegisterScheduledJob(IScheduledJob scheduledJob)
+ {
+ if (_scheduledJobs.TryGetValue(scheduledJob.Name, out var existingScheduledJob)) existingScheduledJob.Cancel();
+ _scheduledJobs[scheduledJob.Name] = scheduledJob;
+ }
+
+ public Task UnscheduleAsync(string name, CancellationToken cancellationToken = default)
+ {
+ if (_scheduledJobs.TryGetValue(name, out var existingScheduledJob)) existingScheduledJob.Cancel();
+ return Task.CompletedTask;
+ }
+
+ public Task ClearAsync(string[]? groupKeys = default, CancellationToken cancellationToken = default)
+ {
+ foreach (var scheduledJob in _scheduledJobs.Values) scheduledJob.Cancel();
+
+ _scheduledJobs.Clear();
+ return Task.CompletedTask;
+ }
+}
\ No newline at end of file
diff --git a/src/common/Elsa.Jobs.Abstractions/Models/JobExecutionContext.cs b/src/modules/Elsa.Jobs/Models/JobExecutionContext.cs
similarity index 100%
rename from src/common/Elsa.Jobs.Abstractions/Models/JobExecutionContext.cs
rename to src/modules/Elsa.Jobs/Models/JobExecutionContext.cs
diff --git a/src/common/Elsa.Jobs.Abstractions/Notifications/JobExecuted.cs b/src/modules/Elsa.Jobs/Notifications/JobExecuted.cs
similarity index 100%
rename from src/common/Elsa.Jobs.Abstractions/Notifications/JobExecuted.cs
rename to src/modules/Elsa.Jobs/Notifications/JobExecuted.cs
diff --git a/src/modules/Elsa.Jobs/ScheduledJobs/ScheduledCronJob.cs b/src/modules/Elsa.Jobs/ScheduledJobs/ScheduledCronJob.cs
new file mode 100644
index 000000000..0ca2039d5
--- /dev/null
+++ b/src/modules/Elsa.Jobs/ScheduledJobs/ScheduledCronJob.cs
@@ -0,0 +1,59 @@
+using System.Threading;
+using Cronos;
+using Elsa.Common.Services;
+using Elsa.Jobs.Services;
+using Timer = System.Timers.Timer;
+
+namespace Elsa.Jobs.ScheduledJobs;
+
+public class ScheduledCronJob : IScheduledJob
+{
+ private readonly IJob _job;
+ private readonly ISystemClock _systemClock;
+ private readonly IJobRunner _jobRunner;
+ private readonly CronExpression _parsedCronExpression;
+ private readonly CancellationToken _cancellationToken;
+ private Timer? _timer;
+
+ public ScheduledCronJob(string name, IJob job, ISystemClock systemClock, string cronExpression, IJobRunner jobRunner, CancellationToken cancellationToken)
+ {
+ Name = name;
+
+ _job = job;
+ _systemClock = systemClock;
+ _parsedCronExpression = CronExpression.Parse(cronExpression);
+ _jobRunner = jobRunner;
+ _cancellationToken = cancellationToken;
+
+ Schedule();
+ }
+
+ public string Name { get; set; }
+ public void Cancel() => _timer?.Dispose();
+
+ private void Schedule()
+ {
+ var now = _systemClock.UtcNow;
+ var parsedCronExpression = _parsedCronExpression;
+ var nextOccurence = parsedCronExpression.GetNextOccurrence(now.UtcDateTime)!;
+
+ var delay = nextOccurence.Value - now;
+
+ if (delay.Milliseconds <= 0)
+ {
+ Schedule();
+ return;
+ }
+
+ _timer = new Timer(delay.TotalMilliseconds);
+
+ _timer.Elapsed += async (_, _) =>
+ {
+ _timer.Dispose();
+ _timer = null;
+
+ if (!_cancellationToken.IsCancellationRequested) await _jobRunner.RunJobAsync(_job, _cancellationToken);
+ if (!_cancellationToken.IsCancellationRequested) Schedule();
+ };
+ }
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Jobs/ScheduledJobs/ScheduledRecurringJob.cs b/src/modules/Elsa.Jobs/ScheduledJobs/ScheduledRecurringJob.cs
new file mode 100644
index 000000000..e6a21bf03
--- /dev/null
+++ b/src/modules/Elsa.Jobs/ScheduledJobs/ScheduledRecurringJob.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Threading;
+using Elsa.Common.Services;
+using Elsa.Jobs.Services;
+using Timer = System.Timers.Timer;
+
+namespace Elsa.Jobs.ScheduledJobs;
+
+public class ScheduledRecurringJob : IScheduledJob
+{
+ private readonly IJob _job;
+ private readonly ISystemClock _systemClock;
+ private readonly TimeSpan _interval;
+ private readonly IJobRunner _jobRunner;
+ private readonly CancellationToken _cancellationToken;
+ private DateTimeOffset _startAt;
+ private Timer? _timer;
+
+ public ScheduledRecurringJob(string name, IJob job, ISystemClock systemClock, DateTimeOffset startAt, TimeSpan interval, IJobRunner jobRunner, CancellationToken cancellationToken)
+ {
+ Name = name;
+ _job = job;
+ _systemClock = systemClock;
+ _startAt = startAt;
+ _interval = interval;
+ _jobRunner = jobRunner;
+ _cancellationToken = cancellationToken;
+
+ Schedule();
+ }
+
+ public string Name { get; set; }
+ public void Cancel() => _timer?.Dispose();
+
+ private void Schedule()
+ {
+ var now = _systemClock.UtcNow;
+ var delay = now - _startAt;
+
+ if (delay.Milliseconds <= 0)
+ {
+ Schedule();
+ return;
+ }
+
+ _timer = new Timer(delay.TotalMilliseconds);
+
+ _timer.Elapsed += async (_, _) =>
+ {
+ _timer.Dispose();
+ _timer = null;
+ _startAt = now + _interval;
+
+ if (!_cancellationToken.IsCancellationRequested) await _jobRunner.RunJobAsync(_job, _cancellationToken);
+ if (!_cancellationToken.IsCancellationRequested) Schedule();
+ };
+ }
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Jobs/ScheduledJobs/ScheduledSpecificInstantJob.cs b/src/modules/Elsa.Jobs/ScheduledJobs/ScheduledSpecificInstantJob.cs
new file mode 100644
index 000000000..d19e60081
--- /dev/null
+++ b/src/modules/Elsa.Jobs/ScheduledJobs/ScheduledSpecificInstantJob.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Threading;
+using Elsa.Common.Services;
+using Elsa.Jobs.Services;
+using Timer = System.Timers.Timer;
+
+namespace Elsa.Jobs.ScheduledJobs;
+
+public class ScheduledSpecificInstantJob : IScheduledJob
+{
+ private readonly IJob _job;
+ private readonly ISystemClock _systemClock;
+ private readonly DateTimeOffset _startAt;
+ private readonly IJobRunner _jobRunner;
+ private readonly CancellationToken _cancellationToken;
+ private Timer? _timer;
+
+ public ScheduledSpecificInstantJob(string name, IJob job, ISystemClock systemClock, DateTimeOffset startAt, IJobRunner jobRunner, CancellationToken cancellationToken)
+ {
+ _job = job;
+ _systemClock = systemClock;
+ _startAt = startAt;
+ _jobRunner = jobRunner;
+ _cancellationToken = cancellationToken;
+ Name = name;
+
+ Schedule();
+ }
+
+ public string Name { get; set; }
+ public void Cancel() => _timer?.Dispose();
+
+ private void Schedule()
+ {
+ var now = _systemClock.UtcNow;
+ var delay = now - _startAt;
+
+ if (delay.Milliseconds <= 0)
+ delay = TimeSpan.Zero;
+
+ _timer = new Timer(delay.TotalMilliseconds);
+
+ _timer.Elapsed += async (_, _) =>
+ {
+ _timer.Dispose();
+ _timer = null;
+
+ if (!_cancellationToken.IsCancellationRequested) await _jobRunner.RunJobAsync(_job, _cancellationToken);
+ };
+ }
+}
\ No newline at end of file
diff --git a/src/common/Elsa.Jobs.Abstractions/Schedules/CronSchedule.cs b/src/modules/Elsa.Jobs/Schedules/CronSchedule.cs
similarity index 100%
rename from src/common/Elsa.Jobs.Abstractions/Schedules/CronSchedule.cs
rename to src/modules/Elsa.Jobs/Schedules/CronSchedule.cs
diff --git a/src/common/Elsa.Jobs.Abstractions/Schedules/RecurringSchedule.cs b/src/modules/Elsa.Jobs/Schedules/RecurringSchedule.cs
similarity index 100%
rename from src/common/Elsa.Jobs.Abstractions/Schedules/RecurringSchedule.cs
rename to src/modules/Elsa.Jobs/Schedules/RecurringSchedule.cs
diff --git a/src/common/Elsa.Jobs.Abstractions/Schedules/SpecificInstantSchedule.cs b/src/modules/Elsa.Jobs/Schedules/SpecificInstantSchedule.cs
similarity index 100%
rename from src/common/Elsa.Jobs.Abstractions/Schedules/SpecificInstantSchedule.cs
rename to src/modules/Elsa.Jobs/Schedules/SpecificInstantSchedule.cs
diff --git a/src/common/Elsa.Jobs.Abstractions/Services/IJob.cs b/src/modules/Elsa.Jobs/Services/IJob.cs
similarity index 69%
rename from src/common/Elsa.Jobs.Abstractions/Services/IJob.cs
rename to src/modules/Elsa.Jobs/Services/IJob.cs
index beb756e5b..9efa49991 100644
--- a/src/common/Elsa.Jobs.Abstractions/Services/IJob.cs
+++ b/src/modules/Elsa.Jobs/Services/IJob.cs
@@ -3,6 +3,9 @@ using Elsa.Jobs.Models;
namespace Elsa.Jobs.Services;
+///
+/// Implemented by types that represent a background job.
+///
public interface IJob
{
string Id { get; set; }
diff --git a/src/common/Elsa.Jobs.Abstractions/Services/IJobFactory.cs b/src/modules/Elsa.Jobs/Services/IJobFactory.cs
similarity index 52%
rename from src/common/Elsa.Jobs.Abstractions/Services/IJobFactory.cs
rename to src/modules/Elsa.Jobs/Services/IJobFactory.cs
index 9d5232ad2..35ca4d4f8 100644
--- a/src/common/Elsa.Jobs.Abstractions/Services/IJobFactory.cs
+++ b/src/modules/Elsa.Jobs/Services/IJobFactory.cs
@@ -3,9 +3,12 @@ using System;
namespace Elsa.Jobs.Services;
///
-/// Instantiates new jobs of a given type.
+/// Instantiates jobs of a given type.
///
public interface IJobFactory
{
+ ///
+ /// Instantiates a job of the specified type.
+ ///
IJob Create(Type jobType);
}
\ No newline at end of file
diff --git a/src/common/Elsa.Jobs.Abstractions/Services/IJobQueue.cs b/src/modules/Elsa.Jobs/Services/IJobQueue.cs
similarity index 63%
rename from src/common/Elsa.Jobs.Abstractions/Services/IJobQueue.cs
rename to src/modules/Elsa.Jobs/Services/IJobQueue.cs
index 7fcf0a2b6..ea5fb5a9e 100644
--- a/src/common/Elsa.Jobs.Abstractions/Services/IJobQueue.cs
+++ b/src/modules/Elsa.Jobs/Services/IJobQueue.cs
@@ -8,5 +8,5 @@ namespace Elsa.Jobs.Services;
///
public interface IJobQueue
{
- Task SubmitJobAsync(IJob job, string? queueName = default, CancellationToken cancellationToken = default);
+ Task SubmitJobAsync(IJob job, string? queueName = default, CancellationToken cancellationToken = default);
}
\ No newline at end of file
diff --git a/src/common/Elsa.Jobs.Abstractions/Services/IJobRunner.cs b/src/modules/Elsa.Jobs/Services/IJobRunner.cs
similarity index 61%
rename from src/common/Elsa.Jobs.Abstractions/Services/IJobRunner.cs
rename to src/modules/Elsa.Jobs/Services/IJobRunner.cs
index 3dd9988ff..a6c3ef172 100644
--- a/src/common/Elsa.Jobs.Abstractions/Services/IJobRunner.cs
+++ b/src/modules/Elsa.Jobs/Services/IJobRunner.cs
@@ -3,7 +3,13 @@ using System.Threading.Tasks;
namespace Elsa.Jobs.Services;
+///
+/// Runs specified jobs.
+///
public interface IJobRunner
{
+ ///
+ /// Runs the specified job.
+ ///
Task RunJobAsync(IJob job, CancellationToken cancellationToken = default);
}
\ No newline at end of file
diff --git a/src/common/Elsa.Jobs.Abstractions/Services/IJobScheduler.cs b/src/modules/Elsa.Jobs/Services/IJobScheduler.cs
similarity index 100%
rename from src/common/Elsa.Jobs.Abstractions/Services/IJobScheduler.cs
rename to src/modules/Elsa.Jobs/Services/IJobScheduler.cs
diff --git a/src/common/Elsa.Jobs.Abstractions/Services/IJobSerializer.cs b/src/modules/Elsa.Jobs/Services/IJobSerializer.cs
similarity index 100%
rename from src/common/Elsa.Jobs.Abstractions/Services/IJobSerializer.cs
rename to src/modules/Elsa.Jobs/Services/IJobSerializer.cs
diff --git a/src/common/Elsa.Jobs.Abstractions/Services/ISchedule.cs b/src/modules/Elsa.Jobs/Services/ISchedule.cs
similarity index 100%
rename from src/common/Elsa.Jobs.Abstractions/Services/ISchedule.cs
rename to src/modules/Elsa.Jobs/Services/ISchedule.cs
diff --git a/src/modules/Elsa.Jobs/Services/IScheduledJob.cs b/src/modules/Elsa.Jobs/Services/IScheduledJob.cs
new file mode 100644
index 000000000..cb61d0713
--- /dev/null
+++ b/src/modules/Elsa.Jobs/Services/IScheduledJob.cs
@@ -0,0 +1,7 @@
+namespace Elsa.Jobs.Services;
+
+internal interface IScheduledJob
+{
+ string Name { get; set; }
+ void Cancel();
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.MassTransit/Extensions/DependencyInjectionExtensions.cs b/src/modules/Elsa.MassTransit/Extensions/DependencyInjectionExtensions.cs
deleted file mode 100644
index 455ae06da..000000000
--- a/src/modules/Elsa.MassTransit/Extensions/DependencyInjectionExtensions.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using Elsa.MassTransit.Implementations;
-using Elsa.Workflows.Runtime.Services;
-using Microsoft.Extensions.DependencyInjection;
-
-namespace Elsa.MassTransit.Extensions;
-
-public static class DependencyInjectionExtensions
-{
- public static IServiceCollection AddMassTransitServices(this IServiceCollection services)
- {
- return services.AddSingleton();
- }
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.MassTransit/Extensions/ModuleExtensions.cs b/src/modules/Elsa.MassTransit/Extensions/ModuleExtensions.cs
new file mode 100644
index 000000000..6f79c3354
--- /dev/null
+++ b/src/modules/Elsa.MassTransit/Extensions/ModuleExtensions.cs
@@ -0,0 +1,13 @@
+using Elsa.Features.Services;
+using Elsa.MassTransit.Features;
+
+namespace Elsa.MassTransit.Extensions;
+
+public static class ModuleExtensions
+{
+ public static IModule AddMassTransitWorkflowDispatchers(this IModule module)
+ {
+ module.Configure();
+ return module;
+ }
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.MassTransit/Features/MassTransitDispatchersFeature.cs b/src/modules/Elsa.MassTransit/Features/MassTransitDispatchersFeature.cs
new file mode 100644
index 000000000..7becd7fab
--- /dev/null
+++ b/src/modules/Elsa.MassTransit/Features/MassTransitDispatchersFeature.cs
@@ -0,0 +1,22 @@
+using Elsa.Features.Abstractions;
+using Elsa.Features.Attributes;
+using Elsa.Features.Services;
+using Elsa.MassTransit.Implementations;
+using Elsa.Workflows.Runtime.Features;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Elsa.MassTransit.Features;
+
+[DependsOn(typeof(WorkflowRuntimeFeature))]
+[DependsOn(typeof(MassTransitServiceBusFeature))]
+public class MassTransitDispatchersFeature : FeatureBase
+{
+ public MassTransitDispatchersFeature(IModule module) : base(module)
+ {
+ }
+
+ public override void Configure()
+ {
+ Module.Configure(f => f.WorkflowDispatcherFactory = ActivatorUtilities.GetServiceOrCreateInstance);
+ }
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.MassTransit/Features/MassTransitServiceBusFeature.cs b/src/modules/Elsa.MassTransit/Features/MassTransitServiceBusFeature.cs
new file mode 100644
index 000000000..7c12cbcb7
--- /dev/null
+++ b/src/modules/Elsa.MassTransit/Features/MassTransitServiceBusFeature.cs
@@ -0,0 +1,19 @@
+using Elsa.Features.Abstractions;
+using Elsa.Features.Services;
+using Elsa.MassTransit.Implementations;
+using Elsa.ServiceBus.Abstractions.Services;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Elsa.MassTransit.Features;
+
+public class MassTransitServiceBusFeature : FeatureBase
+{
+ public MassTransitServiceBusFeature(IModule module) : base(module)
+ {
+ }
+
+ public override void Apply()
+ {
+ Services.AddSingleton();
+ }
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.MassTransit/Implementations/MassTransitServiceBusProvider.cs b/src/modules/Elsa.MassTransit/Implementations/MassTransitServiceBusProvider.cs
deleted file mode 100644
index fe9754e58..000000000
--- a/src/modules/Elsa.MassTransit/Implementations/MassTransitServiceBusProvider.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using Elsa.ServiceBus.Abstractions.Services;
-using Microsoft.Extensions.DependencyInjection;
-
-namespace Elsa.MassTransit.Implementations;
-
-///
-/// A MassTransit implementation for .
-///
-public class MassTransitServiceBusProvider : IServiceBusProvider
-{
- public void ConfigureServices(IServiceCollection services)
- {
- services
- .AddSingleton();
- }
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Mediator/Elsa.Mediator.csproj b/src/modules/Elsa.Mediator/Elsa.Mediator.csproj
index 4acb383cb..3999c6973 100644
--- a/src/modules/Elsa.Mediator/Elsa.Mediator.csproj
+++ b/src/modules/Elsa.Mediator/Elsa.Mediator.csproj
@@ -8,6 +8,7 @@
+
diff --git a/src/modules/Elsa.Mediator/Extensions/DependencyInjectionExtensions.cs b/src/modules/Elsa.Mediator/Extensions/DependencyInjectionExtensions.cs
index a328e86ba..019be8f98 100644
--- a/src/modules/Elsa.Mediator/Extensions/DependencyInjectionExtensions.cs
+++ b/src/modules/Elsa.Mediator/Extensions/DependencyInjectionExtensions.cs
@@ -1,4 +1,5 @@
using System.Reflection;
+using System.Threading.Channels;
using Elsa.Mediator.Implementations;
using Elsa.Mediator.Middleware.Command;
using Elsa.Mediator.Middleware.Command.Contracts;
@@ -10,6 +11,7 @@ using Elsa.Mediator.Models;
using Elsa.Mediator.Services;
using Elsa.Features.Services;
using Elsa.Mediator.Features;
+using Elsa.Mediator.HostedServices;
using Microsoft.Extensions.DependencyInjection;
namespace Elsa.Mediator.Extensions;
@@ -29,9 +31,16 @@ public static class DependencyInjectionExtensions
.AddSingleton(sp => sp.GetRequiredService())
.AddSingleton(sp => sp.GetRequiredService())
.AddSingleton(sp => sp.GetRequiredService())
+ .AddSingleton()
+ .AddSingleton()
.AddSingleton()
.AddSingleton()
- .AddSingleton();
+ .AddSingleton()
+ .AddHostedService()
+ .AddHostedService()
+ .CreateChannel()
+ .CreateChannel()
+ ;
}
public static IServiceCollection AddCommandHandler(this IServiceCollection services)
@@ -76,6 +85,12 @@ public static class DependencyInjectionExtensions
public static IServiceCollection AddCommandHandlersFrom(this IServiceCollection services, Type markerType) => services.AddHandlersFromInternal(markerType);
public static IServiceCollection AddCommandHandlersFrom(this IServiceCollection services, Assembly assembly) => services.AddHandlersFromInternal(assembly);
+ public static IServiceCollection CreateChannel(this IServiceCollection services) =>
+ services
+ .AddSingleton(CreateChannel())
+ .AddSingleton(CreateChannelReader)
+ .AddSingleton(CreateChannelWriter);
+
private static IServiceCollection AddHandlersFromInternal(this IServiceCollection services) => services.AddHandlersFromInternal(typeof(TMarker));
private static IServiceCollection AddHandlersFromInternal(this IServiceCollection services, Type assemblyMarkerType) => services.AddHandlersFromInternal(assemblyMarkerType.Assembly);
@@ -90,4 +105,8 @@ public static class DependencyInjectionExtensions
return services;
}
+
+ private static Channel CreateChannel() => Channel.CreateUnbounded(new UnboundedChannelOptions());
+ private static ChannelReader CreateChannelReader(IServiceProvider serviceProvider) => serviceProvider.GetRequiredService>().Reader;
+ private static ChannelWriter CreateChannelWriter(IServiceProvider serviceProvider) => serviceProvider.GetRequiredService>().Writer;
}
\ No newline at end of file
diff --git a/src/modules/Elsa.Mediator/HostedServices/BackgroundCommandSenderHostedService.cs b/src/modules/Elsa.Mediator/HostedServices/BackgroundCommandSenderHostedService.cs
new file mode 100644
index 000000000..47b160e8a
--- /dev/null
+++ b/src/modules/Elsa.Mediator/HostedServices/BackgroundCommandSenderHostedService.cs
@@ -0,0 +1,38 @@
+using System.Threading.Channels;
+using Elsa.Mediator.Services;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+
+namespace Elsa.Mediator.HostedServices;
+
+///
+/// Continuously reads from a channel to which commands can be sent, executing each received command.
+///
+public class BackgroundCommandSenderHostedService : BackgroundService
+{
+ private readonly ChannelReader _channelReader;
+ private readonly ICommandSender _commandSender;
+ private readonly ILogger _logger;
+
+ public BackgroundCommandSenderHostedService(ChannelReader channelReader, ICommandSender commandSender, ILogger logger)
+ {
+ _channelReader = channelReader;
+ _commandSender = commandSender;
+ _logger = logger;
+ }
+
+ protected override async Task ExecuteAsync(CancellationToken cancellationToken)
+ {
+ await foreach (var request in _channelReader.ReadAllAsync(cancellationToken))
+ {
+ try
+ {
+ await _commandSender.ExecuteAsync(request, cancellationToken);
+ }
+ catch (Exception e)
+ {
+ _logger.LogError(e, "An unhandled exception occured while processing the queue");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Mediator/HostedServices/BackgroundEventPublisherHostedService.cs b/src/modules/Elsa.Mediator/HostedServices/BackgroundEventPublisherHostedService.cs
new file mode 100644
index 000000000..24db7b7fa
--- /dev/null
+++ b/src/modules/Elsa.Mediator/HostedServices/BackgroundEventPublisherHostedService.cs
@@ -0,0 +1,38 @@
+using System.Threading.Channels;
+using Elsa.Mediator.Services;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+
+namespace Elsa.Mediator.HostedServices;
+
+///
+/// Continuously reads from a channel to which notifications can be sent, publishing each received notification.
+///
+public class BackgroundEventPublisherHostedService : BackgroundService
+{
+ private readonly ChannelReader _channelReader;
+ private readonly IEventPublisher _eventPublisher;
+ private readonly ILogger _logger;
+
+ public BackgroundEventPublisherHostedService(ChannelReader channelReader, IEventPublisher eventPublisher, ILogger logger)
+ {
+ _channelReader = channelReader;
+ _eventPublisher = eventPublisher;
+ _logger = logger;
+ }
+
+ protected override async Task ExecuteAsync(CancellationToken cancellationToken)
+ {
+ await foreach (var notification in _channelReader.ReadAllAsync(cancellationToken))
+ {
+ try
+ {
+ await _eventPublisher.PublishAsync(notification, cancellationToken);
+ }
+ catch (Exception e)
+ {
+ _logger.LogError(e, "An unhandled exception occured while processing the queue");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Mediator/Implementations/BackgroundCommandSender.cs b/src/modules/Elsa.Mediator/Implementations/BackgroundCommandSender.cs
new file mode 100644
index 000000000..7848af618
--- /dev/null
+++ b/src/modules/Elsa.Mediator/Implementations/BackgroundCommandSender.cs
@@ -0,0 +1,11 @@
+using System.Threading.Channels;
+using Elsa.Mediator.Services;
+
+namespace Elsa.Mediator.Implementations;
+
+public class BackgroundCommandSender : IBackgroundCommandSender
+{
+ private readonly ChannelWriter _channelWriter;
+ public BackgroundCommandSender(ChannelWriter channelWriter) => _channelWriter = channelWriter;
+ public async Task SendAsync(ICommand command, CancellationToken cancellationToken = default) => await _channelWriter.WriteAsync(command, cancellationToken);
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Mediator/Implementations/BackgroundEventPublisher.cs b/src/modules/Elsa.Mediator/Implementations/BackgroundEventPublisher.cs
new file mode 100644
index 000000000..a6a79d58a
--- /dev/null
+++ b/src/modules/Elsa.Mediator/Implementations/BackgroundEventPublisher.cs
@@ -0,0 +1,11 @@
+using System.Threading.Channels;
+using Elsa.Mediator.Services;
+
+namespace Elsa.Mediator.Implementations;
+
+public class BackgroundEventPublisher : IBackgroundEventPublisher
+{
+ private readonly ChannelWriter _channelWriter;
+ public BackgroundEventPublisher(ChannelWriter channelWriter) => _channelWriter = channelWriter;
+ public async Task PublishAsync(INotification notification, CancellationToken cancellationToken = default) => await _channelWriter.WriteAsync(notification, cancellationToken);
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Mediator/Services/IBackgroundCommandSender.cs b/src/modules/Elsa.Mediator/Services/IBackgroundCommandSender.cs
new file mode 100644
index 000000000..e6ce0d283
--- /dev/null
+++ b/src/modules/Elsa.Mediator/Services/IBackgroundCommandSender.cs
@@ -0,0 +1,12 @@
+namespace Elsa.Mediator.Services;
+
+///
+/// Send requests to be processed asynchronously in the background.
+///
+public interface IBackgroundCommandSender
+{
+ ///
+ /// Submits the specified command to a channel writer. The channel is processed asynchronously from a background service.
+ ///
+ Task SendAsync(ICommand command, CancellationToken cancellationToken = default);
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Mediator/Services/IBackgroundEventPublisher.cs b/src/modules/Elsa.Mediator/Services/IBackgroundEventPublisher.cs
new file mode 100644
index 000000000..b21385dbe
--- /dev/null
+++ b/src/modules/Elsa.Mediator/Services/IBackgroundEventPublisher.cs
@@ -0,0 +1,12 @@
+namespace Elsa.Mediator.Services;
+
+///
+/// Publish notifications to be processed asynchronously in the background.
+///
+public interface IBackgroundEventPublisher
+{
+ ///
+ /// Publish the specified notification using from a background service.
+ ///
+ Task PublishAsync(INotification notification, CancellationToken cancellationToken = default);
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.ProtoActor/Grains/WorkflowInstanceGrain.cs b/src/modules/Elsa.ProtoActor/Grains/WorkflowInstanceGrain.cs
index af15a3777..aa16ddba2 100644
--- a/src/modules/Elsa.ProtoActor/Grains/WorkflowInstanceGrain.cs
+++ b/src/modules/Elsa.ProtoActor/Grains/WorkflowInstanceGrain.cs
@@ -12,7 +12,6 @@ using Elsa.Workflows.Core.Serialization;
using Elsa.Workflows.Core.Services;
using Elsa.Workflows.Core.State;
using Elsa.Workflows.Persistence.Entities;
-using Elsa.Workflows.Persistence.Models;
using Elsa.Workflows.Persistence.Services;
using Elsa.Workflows.Runtime.Services;
using Proto;
diff --git a/src/modules/Elsa.ProtoActor/Implementations/GrainClientFactory.cs b/src/modules/Elsa.ProtoActor/Implementations/GrainClientFactory.cs
index 63d76de6c..b09b7b437 100644
--- a/src/modules/Elsa.ProtoActor/Implementations/GrainClientFactory.cs
+++ b/src/modules/Elsa.ProtoActor/Implementations/GrainClientFactory.cs
@@ -1,6 +1,5 @@
using Elsa.Persistence.Common.Models;
using Elsa.Runtime.Protos;
-using Elsa.Workflows.Persistence.Models;
using Proto.Cluster;
namespace Elsa.ProtoActor.Implementations;
diff --git a/src/modules/Elsa.ProtoActor/Implementations/ProtoActorWorkflowInvoker.cs b/src/modules/Elsa.ProtoActor/Implementations/ProtoActorWorkflowInvoker.cs
index 0fa3acded..537cd8af3 100644
--- a/src/modules/Elsa.ProtoActor/Implementations/ProtoActorWorkflowInvoker.cs
+++ b/src/modules/Elsa.ProtoActor/Implementations/ProtoActorWorkflowInvoker.cs
@@ -11,7 +11,6 @@ using Elsa.Workflows.Core.Models;
using Elsa.Workflows.Core.Serialization;
using Elsa.Workflows.Core.State;
using Elsa.Workflows.Persistence.Entities;
-using Elsa.Workflows.Persistence.Models;
using Elsa.Workflows.Runtime.Models;
using Elsa.Workflows.Runtime.Services;
using Proto;
diff --git a/src/modules/Elsa.Quartz/Elsa.Quartz.csproj b/src/modules/Elsa.Quartz/Elsa.Quartz.csproj
index faf77ed30..233bf88af 100644
--- a/src/modules/Elsa.Quartz/Elsa.Quartz.csproj
+++ b/src/modules/Elsa.Quartz/Elsa.Quartz.csproj
@@ -13,7 +13,7 @@
-
+
diff --git a/src/modules/Elsa.Quartz/Features/QuartzFeature.cs b/src/modules/Elsa.Quartz/Features/QuartzFeature.cs
new file mode 100644
index 000000000..42ca1e320
--- /dev/null
+++ b/src/modules/Elsa.Quartz/Features/QuartzFeature.cs
@@ -0,0 +1,48 @@
+using Elsa.Features.Abstractions;
+using Elsa.Features.Services;
+using Elsa.Quartz.Extensions;
+using Microsoft.Extensions.DependencyInjection;
+using Quartz;
+
+namespace Elsa.Quartz.Features;
+
+public class QuartzFeature : FeatureBase
+{
+ public QuartzFeature(IModule module) : base(module)
+ {
+ }
+
+ public Action? ConfigureQuartzOptions { get; set; }
+ public Action? ConfigureQuartz { get; set; }
+ public Action? ConfigureQuartzHostedService { get; set; }
+
+ public override void Configure()
+ {
+ if (ConfigureQuartzOptions != null)
+ Services.Configure(ConfigureQuartzOptions);
+
+ Services
+ .AddQuartz(configure =>
+ {
+ ConfigureQuartzInternal(configure, ConfigureQuartz);
+ configure.AddElsaJobs();
+ });
+ }
+
+ public override void ConfigureHostedServices()
+ {
+ Services.AddQuartzHostedService(options =>
+ {
+ options.WaitForJobsToComplete = true;
+ ConfigureQuartzHostedService?.Invoke(options);
+ });
+ }
+
+ private static void ConfigureQuartzInternal(IServiceCollectionQuartzConfigurator quartz, Action? configureQuartz)
+ {
+ quartz.UseMicrosoftDependencyInjectionJobFactory();
+ quartz.UseSimpleTypeLoader();
+ quartz.UseInMemoryStore();
+ configureQuartz?.Invoke(quartz);
+ }
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Quartz/Features/QuartzSchedulerFeature.cs b/src/modules/Elsa.Quartz/Features/QuartzSchedulerFeature.cs
new file mode 100644
index 000000000..12d76618a
--- /dev/null
+++ b/src/modules/Elsa.Quartz/Features/QuartzSchedulerFeature.cs
@@ -0,0 +1,22 @@
+using Elsa.Features.Abstractions;
+using Elsa.Features.Attributes;
+using Elsa.Features.Services;
+using Elsa.Jobs.Features;
+using Elsa.Quartz.Implementations;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Elsa.Quartz.Features;
+
+[DependsOn(typeof(JobsFeature))]
+[DependsOn(typeof(QuartzFeature))]
+public class QuartzSchedulerFeature : FeatureBase
+{
+ public QuartzSchedulerFeature(IModule module) : base(module)
+ {
+ }
+
+ public override void Configure()
+ {
+ Module.Configure(f => f.JobSchedulerFactory = ActivatorUtilities.GetServiceOrCreateInstance);
+ }
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Quartz/Implementations/QuartzJobScheduler.cs b/src/modules/Elsa.Quartz/Implementations/QuartzJobScheduler.cs
index 9c7f7d890..5749deccc 100644
--- a/src/modules/Elsa.Quartz/Implementations/QuartzJobScheduler.cs
+++ b/src/modules/Elsa.Quartz/Implementations/QuartzJobScheduler.cs
@@ -87,7 +87,7 @@ public class QuartzJobScheduler : IJobScheduler
}
default:
- throw new NotSupportedException($"Schedule of type {schedule.GetType()} is not supported. But if you create an issue, we'll make this logic extensible & replaceable :)");
+ throw new NotSupportedException($"Schedule of type {schedule.GetType()} is not supported.");
}
return builder.Build();
diff --git a/src/modules/Elsa.Quartz/Implementations/QuartzJobSchedulerProvider.cs b/src/modules/Elsa.Quartz/Implementations/QuartzJobSchedulerProvider.cs
deleted file mode 100644
index 17a916963..000000000
--- a/src/modules/Elsa.Quartz/Implementations/QuartzJobSchedulerProvider.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-using Elsa.Jobs.Services;
-using Elsa.Quartz.Extensions;
-using Microsoft.Extensions.DependencyInjection;
-using Quartz;
-
-namespace Elsa.Quartz.Implementations;
-
-///
-/// A Quartz.NET implementation for .
-///
-public class QuartzJobSchedulerProvider : IJobSchedulerProvider
-{
- public QuartzJobSchedulerProvider(bool registerQuartz = true)
- {
- RegisterQuartz = registerQuartz;
- }
-
- public QuartzJobSchedulerProvider(Action configureQuartzOptions)
- {
- RegisterQuartz = true;
- ConfigureQuartzOptions = configureQuartzOptions;
- }
-
- public QuartzJobSchedulerProvider(
- Action configureQuartzOptions,
- Action configureQuartz)
- {
- RegisterQuartz = true;
- ConfigureQuartzOptions = configureQuartzOptions;
- ConfigureQuartz = configureQuartz;
- }
-
- public QuartzJobSchedulerProvider(
- Action configureQuartzOptions,
- Action configureQuartz,
- Action configureQuartzHostedService)
- {
- RegisterQuartz = true;
- ConfigureQuartzOptions = configureQuartzOptions;
- ConfigureQuartz = configureQuartz;
- ConfigureQuartzHostedService = configureQuartzHostedService;
- }
-
- public bool RegisterQuartz { get; set; }
- public Action? ConfigureQuartzOptions { get; set; }
- public Action? ConfigureQuartz { get; set; }
- public Action? ConfigureQuartzHostedService { get; set; }
-
- public void ConfigureServices(IServiceCollection services)
- {
- if (RegisterQuartz)
- {
- if (ConfigureQuartzOptions != null)
- services.Configure(ConfigureQuartzOptions);
-
- services
- .AddQuartz(configure =>
- {
- ConfigureQuartzInternal(configure, ConfigureQuartz);
- configure.AddElsaJobs();
- })
- .AddQuartzHostedService(options =>
- {
- options.WaitForJobsToComplete = true;
- ConfigureQuartzHostedService?.Invoke(options);
- });
- }
-
- services.AddSingleton();
-
- }
-
- private static void ConfigureQuartzInternal(IServiceCollectionQuartzConfigurator quartz, Action? configureQuartz)
- {
- quartz.UseMicrosoftDependencyInjectionJobFactory();
- quartz.UseSimpleTypeLoader();
- quartz.UseInMemoryStore();
- configureQuartz?.Invoke(quartz);
- }
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Scheduling/Activities/Delay.cs b/src/modules/Elsa.Scheduling/Activities/Delay.cs
index cae72d253..151fec374 100644
--- a/src/modules/Elsa.Scheduling/Activities/Delay.cs
+++ b/src/modules/Elsa.Scheduling/Activities/Delay.cs
@@ -1,4 +1,5 @@
using System;
+using Elsa.Common.Services;
using Elsa.Workflows.Core;
using Elsa.Workflows.Core.Attributes;
using Elsa.Workflows.Core.Models;
diff --git a/src/modules/Elsa.Scheduling/Activities/StartAt.cs b/src/modules/Elsa.Scheduling/Activities/StartAt.cs
index 07a02b2bf..a598106c8 100644
--- a/src/modules/Elsa.Scheduling/Activities/StartAt.cs
+++ b/src/modules/Elsa.Scheduling/Activities/StartAt.cs
@@ -1,5 +1,6 @@
using System;
using System.Threading.Tasks;
+using Elsa.Common.Services;
using Elsa.Expressions.Models;
using Elsa.Workflows.Core;
using Elsa.Workflows.Core.Attributes;
diff --git a/src/modules/Elsa.Scheduling/Activities/Timer.cs b/src/modules/Elsa.Scheduling/Activities/Timer.cs
index 34ad1fbd2..299c52e18 100644
--- a/src/modules/Elsa.Scheduling/Activities/Timer.cs
+++ b/src/modules/Elsa.Scheduling/Activities/Timer.cs
@@ -1,5 +1,6 @@
using System;
using System.Text.Json.Serialization;
+using Elsa.Common.Services;
using Elsa.Workflows.Core;
using Elsa.Workflows.Core.Attributes;
using Elsa.Workflows.Core.Models;
diff --git a/src/modules/Elsa.Scheduling/Elsa.Scheduling.csproj b/src/modules/Elsa.Scheduling/Elsa.Scheduling.csproj
index 6c746d054..fb5bbc108 100644
--- a/src/modules/Elsa.Scheduling/Elsa.Scheduling.csproj
+++ b/src/modules/Elsa.Scheduling/Elsa.Scheduling.csproj
@@ -7,7 +7,7 @@
-
+
diff --git a/src/modules/Elsa.Scheduling/Extensions/DependencyInjectionExtensions.cs b/src/modules/Elsa.Scheduling/Extensions/DependencyInjectionExtensions.cs
deleted file mode 100644
index ad0c8a0d4..000000000
--- a/src/modules/Elsa.Scheduling/Extensions/DependencyInjectionExtensions.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using Elsa.Mediator.Extensions;
-using Elsa.Scheduling.Implementations;
-using Elsa.Scheduling.Services;
-using Microsoft.Extensions.DependencyInjection;
-
-namespace Elsa.Scheduling.Extensions;
-
-public static class DependencyInjectionExtensions
-{
- public static IServiceCollection AddSchedulingServices(this IServiceCollection services)
- {
- services
- .AddSingleton()
- .AddSingleton()
- .AddNotificationHandlersFrom()
- .AddHostedService();
-
- return services;
- }
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Scheduling/Extensions/ModuleExtensions.cs b/src/modules/Elsa.Scheduling/Extensions/ModuleExtensions.cs
new file mode 100644
index 000000000..9b304a110
--- /dev/null
+++ b/src/modules/Elsa.Scheduling/Extensions/ModuleExtensions.cs
@@ -0,0 +1,14 @@
+using System;
+using Elsa.Features.Services;
+using Elsa.Scheduling.Features;
+
+namespace Elsa.Scheduling.Extensions;
+
+public static class ModuleExtensions
+{
+ public static IModule UseScheduling(this IModule module, Action? configure = default )
+ {
+ module.Configure(configure);
+ return module;
+ }
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Scheduling/Features/SchedulingFeature.cs b/src/modules/Elsa.Scheduling/Features/SchedulingFeature.cs
new file mode 100644
index 000000000..2311ad35d
--- /dev/null
+++ b/src/modules/Elsa.Scheduling/Features/SchedulingFeature.cs
@@ -0,0 +1,32 @@
+using Elsa.Common.Features;
+using Elsa.Features.Abstractions;
+using Elsa.Features.Attributes;
+using Elsa.Features.Services;
+using Elsa.Mediator.Extensions;
+using Elsa.Scheduling.HostedServices;
+using Elsa.Scheduling.Implementations;
+using Elsa.Scheduling.Services;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Elsa.Scheduling.Features;
+
+[DependsOn(typeof(SystemClockFeature))]
+public class SchedulingFeature : FeatureBase
+{
+ public SchedulingFeature(IModule module) : base(module)
+ {
+ }
+
+ public override void ConfigureHostedServices()
+ {
+ Services.AddHostedService();
+ }
+
+ public override void Apply()
+ {
+ Services
+ .AddSingleton()
+ .AddSingleton()
+ .AddNotificationHandlersFrom();
+ }
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Scheduling/HostedServices/ScheduleWorkflows.cs b/src/modules/Elsa.Scheduling/HostedServices/ScheduleWorkflowsHostedService.cs
similarity index 88%
rename from src/modules/Elsa.Scheduling/HostedServices/ScheduleWorkflows.cs
rename to src/modules/Elsa.Scheduling/HostedServices/ScheduleWorkflowsHostedService.cs
index bd9aabba6..2d0317644 100644
--- a/src/modules/Elsa.Scheduling/HostedServices/ScheduleWorkflows.cs
+++ b/src/modules/Elsa.Scheduling/HostedServices/ScheduleWorkflowsHostedService.cs
@@ -13,12 +13,12 @@ namespace Elsa.Scheduling.HostedServices;
///
/// Loads all timer-specific workflow bookmarks from the database and create scheduled jobs for them.
///
-public class ScheduleWorkflows : BackgroundService
+public class ScheduleWorkflowsHostedService : BackgroundService
{
private readonly IWorkflowBookmarkStore _bookmarkStore;
private readonly IWorkflowBookmarkScheduler _workflowBookmarkScheduler;
- public ScheduleWorkflows(IWorkflowBookmarkStore bookmarkStore, IWorkflowBookmarkScheduler workflowBookmarkScheduler)
+ public ScheduleWorkflowsHostedService(IWorkflowBookmarkStore bookmarkStore, IWorkflowBookmarkScheduler workflowBookmarkScheduler)
{
_bookmarkStore = bookmarkStore;
_workflowBookmarkScheduler = workflowBookmarkScheduler;
diff --git a/src/modules/Elsa.Scheduling/Jobs/RunWorkflowJob.cs b/src/modules/Elsa.Scheduling/Jobs/RunWorkflowJob.cs
index b3489af1b..95cafb03d 100644
--- a/src/modules/Elsa.Scheduling/Jobs/RunWorkflowJob.cs
+++ b/src/modules/Elsa.Scheduling/Jobs/RunWorkflowJob.cs
@@ -4,7 +4,6 @@ using System.Threading.Tasks;
using Elsa.Jobs.Abstractions;
using Elsa.Jobs.Models;
using Elsa.Persistence.Common.Models;
-using Elsa.Workflows.Persistence.Models;
using Elsa.Workflows.Runtime.Models;
using Elsa.Workflows.Runtime.Services;
diff --git a/src/modules/Elsa.Workflows.Api/ApiResults/DispatchWorkflowDefinitionResult.cs b/src/modules/Elsa.Workflows.Api/ApiResults/DispatchWorkflowDefinitionResult.cs
index d83f72189..fc5b055e3 100644
--- a/src/modules/Elsa.Workflows.Api/ApiResults/DispatchWorkflowDefinitionResult.cs
+++ b/src/modules/Elsa.Workflows.Api/ApiResults/DispatchWorkflowDefinitionResult.cs
@@ -1,7 +1,6 @@
using System.Net;
using System.Threading.Tasks;
using Elsa.Persistence.Common.Models;
-using Elsa.Workflows.Persistence.Models;
using Elsa.Workflows.Runtime.Models;
using Elsa.Workflows.Runtime.Services;
using Microsoft.AspNetCore.Http;
diff --git a/src/modules/Elsa.Workflows.Api/ApiResults/ExecuteWorkflowDefinitionResult.cs b/src/modules/Elsa.Workflows.Api/ApiResults/ExecuteWorkflowDefinitionResult.cs
index 8efcc81a1..ffd9f02a6 100644
--- a/src/modules/Elsa.Workflows.Api/ApiResults/ExecuteWorkflowDefinitionResult.cs
+++ b/src/modules/Elsa.Workflows.Api/ApiResults/ExecuteWorkflowDefinitionResult.cs
@@ -2,7 +2,6 @@ using System.Threading;
using System.Threading.Tasks;
using Elsa.Persistence.Common.Models;
using Elsa.Workflows.Core.Serialization;
-using Elsa.Workflows.Persistence.Models;
using Elsa.Workflows.Runtime.Models;
using Elsa.Workflows.Runtime.Services;
using Microsoft.AspNetCore.Http;
diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/BulkDelete.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/BulkDelete.cs
index 9ab54bfa7..8fb7c668b 100644
--- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/BulkDelete.cs
+++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/BulkDelete.cs
@@ -5,7 +5,6 @@ using System.Threading.Tasks;
using Elsa.AspNetCore.Attributes;
using Elsa.Workflows.Core.Serialization;
using Elsa.Workflows.Management.Services;
-using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/BulkPublish.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/BulkPublish.cs
index f53ac255c..af34db6bb 100644
--- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/BulkPublish.cs
+++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/BulkPublish.cs
@@ -5,7 +5,6 @@ using Elsa.AspNetCore.Attributes;
using Elsa.Persistence.Common.Models;
using Elsa.Workflows.Core.Serialization;
using Elsa.Workflows.Management.Services;
-using Elsa.Workflows.Persistence.Models;
using Elsa.Workflows.Persistence.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/BulkRetract.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/BulkRetract.cs
index a9121cc9e..f6cb402d9 100644
--- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/BulkRetract.cs
+++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/BulkRetract.cs
@@ -5,7 +5,6 @@ using Elsa.AspNetCore.Attributes;
using Elsa.Persistence.Common.Models;
using Elsa.Workflows.Core.Serialization;
using Elsa.Workflows.Management.Services;
-using Elsa.Workflows.Persistence.Models;
using Elsa.Workflows.Persistence.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Dispatch.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Dispatch.cs
index 0985f8de0..8fdb21035 100644
--- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Dispatch.cs
+++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Dispatch.cs
@@ -3,7 +3,6 @@ using System.Threading.Tasks;
using Elsa.AspNetCore.Attributes;
using Elsa.Persistence.Common.Models;
using Elsa.Workflows.Api.ApiResults;
-using Elsa.Workflows.Persistence.Models;
using Elsa.Workflows.Persistence.Services;
using Elsa.Workflows.Runtime.Models;
using Microsoft.AspNetCore.Http;
diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Execute.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Execute.cs
index b7e19a11d..175135e59 100644
--- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Execute.cs
+++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Execute.cs
@@ -4,7 +4,6 @@ using Elsa.AspNetCore.Attributes;
using Elsa.Persistence.Common.Models;
using Elsa.Workflows.Api.ApiResults;
using Elsa.Workflows.Core.Models;
-using Elsa.Workflows.Persistence.Models;
using Elsa.Workflows.Persistence.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Export.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Export.cs
index f09871f79..663d536bc 100644
--- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Export.cs
+++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Export.cs
@@ -8,7 +8,6 @@ using Elsa.Persistence.Common.Models;
using Elsa.Workflows.Api.Models;
using Elsa.Workflows.Core.Serialization;
using Elsa.Workflows.Management.Mappers;
-using Elsa.Workflows.Persistence.Models;
using Elsa.Workflows.Persistence.Services;
using Elsa.Workflows.Runtime.Services;
using Humanizer;
diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Get.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Get.cs
index 87f0e87ce..85d2b3263 100644
--- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Get.cs
+++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Get.cs
@@ -6,7 +6,6 @@ using Elsa.Persistence.Common.Models;
using Elsa.Workflows.Api.Models;
using Elsa.Workflows.Core.Serialization;
using Elsa.Workflows.Management.Mappers;
-using Elsa.Workflows.Persistence.Models;
using Elsa.Workflows.Persistence.Services;
using Elsa.Workflows.Runtime.Services;
using Microsoft.AspNetCore.Http;
diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Post.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Post.cs
index ae935b405..1feb1b9ad 100644
--- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Post.cs
+++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Post.cs
@@ -13,7 +13,6 @@ using Elsa.Workflows.Management.Materializers;
using Elsa.Workflows.Management.Models;
using Elsa.Workflows.Management.Services;
using Elsa.Workflows.Persistence.Entities;
-using Elsa.Workflows.Persistence.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Publish.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Publish.cs
index 1a32911da..eeac84c1c 100644
--- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Publish.cs
+++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Publish.cs
@@ -5,7 +5,6 @@ using Elsa.Persistence.Common.Models;
using Elsa.Workflows.Core.Serialization;
using Elsa.Workflows.Management.Services;
using Elsa.Workflows.Persistence.Entities;
-using Elsa.Workflows.Persistence.Models;
using Elsa.Workflows.Persistence.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Retract.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Retract.cs
index 1f12f5723..37c37fc78 100644
--- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Retract.cs
+++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Retract.cs
@@ -5,7 +5,6 @@ using Elsa.Persistence.Common.Models;
using Elsa.Workflows.Core.Serialization;
using Elsa.Workflows.Management.Services;
using Elsa.Workflows.Persistence.Entities;
-using Elsa.Workflows.Persistence.Models;
using Elsa.Workflows.Persistence.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
diff --git a/src/modules/Elsa.Workflows.Api/Models/WorkflowDefinitionModel.cs b/src/modules/Elsa.Workflows.Api/Models/WorkflowDefinitionModel.cs
index 2fcfd5fb9..e6cbe2b76 100644
--- a/src/modules/Elsa.Workflows.Api/Models/WorkflowDefinitionModel.cs
+++ b/src/modules/Elsa.Workflows.Api/Models/WorkflowDefinitionModel.cs
@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using Elsa.Workflows.Core.Services;
using Elsa.Workflows.Management.Models;
-using Elsa.Workflows.Persistence.Models;
namespace Elsa.Workflows.Api.Models;
diff --git a/src/modules/Elsa.Workflows.Core/Elsa.Workflows.Core.csproj b/src/modules/Elsa.Workflows.Core/Elsa.Workflows.Core.csproj
index 2fcf7a69d..eebe78a67 100644
--- a/src/modules/Elsa.Workflows.Core/Elsa.Workflows.Core.csproj
+++ b/src/modules/Elsa.Workflows.Core/Elsa.Workflows.Core.csproj
@@ -18,6 +18,7 @@
+
diff --git a/src/modules/Elsa.Workflows.Core/Extensions/ActivityExecutionContextExtensions.cs b/src/modules/Elsa.Workflows.Core/Extensions/ActivityExecutionContextExtensions.cs
index 6ecbe6f8b..fe9f4988a 100644
--- a/src/modules/Elsa.Workflows.Core/Extensions/ActivityExecutionContextExtensions.cs
+++ b/src/modules/Elsa.Workflows.Core/Extensions/ActivityExecutionContextExtensions.cs
@@ -1,4 +1,5 @@
using System.Linq.Expressions;
+using Elsa.Common.Services;
using Elsa.Expressions.Services;
using Elsa.Workflows.Core.Models;
using Elsa.Workflows.Core.Services;
diff --git a/src/modules/Elsa.Workflows.Core/Features/WorkflowsFeature.cs b/src/modules/Elsa.Workflows.Core/Features/WorkflowsFeature.cs
index beb46aeaa..237bb3e9d 100644
--- a/src/modules/Elsa.Workflows.Core/Features/WorkflowsFeature.cs
+++ b/src/modules/Elsa.Workflows.Core/Features/WorkflowsFeature.cs
@@ -1,3 +1,4 @@
+using Elsa.Common.Features;
using Elsa.Expressions;
using Elsa.Expressions.Extensions;
using Elsa.Expressions.Features;
@@ -16,6 +17,7 @@ using Microsoft.Extensions.DependencyInjection;
namespace Elsa.Workflows.Core.Features;
+[DependsOn(typeof(SystemClockFeature))]
[DependsOn(typeof(ExpressionsFeature))]
public class WorkflowsFeature : FeatureBase
{
@@ -64,7 +66,6 @@ public class WorkflowsFeature : FeatureBase
.AddSingleton()
.AddSingleton()
.AddSingleton()
- .AddSingleton()
.AddSingleton()
.AddTransient()
.AddSingleton(typeof(Func), sp => () => sp.GetRequiredService())
diff --git a/src/modules/Elsa.Workflows.Core/Pipelines/ActivityExecution/Components/ActivityInvokerMiddleware.cs b/src/modules/Elsa.Workflows.Core/Pipelines/ActivityExecution/Components/ActivityInvokerMiddleware.cs
index cd9413e6d..23dd02a61 100644
--- a/src/modules/Elsa.Workflows.Core/Pipelines/ActivityExecution/Components/ActivityInvokerMiddleware.cs
+++ b/src/modules/Elsa.Workflows.Core/Pipelines/ActivityExecution/Components/ActivityInvokerMiddleware.cs
@@ -1,3 +1,4 @@
+using Elsa.Common.Services;
using Elsa.Workflows.Core.Models;
using Elsa.Workflows.Core.Services;
using Microsoft.Extensions.Logging;
@@ -13,13 +14,13 @@ public static class InvokeDriversMiddlewareExtensions
public class ActivityInvokerMiddleware : IActivityExecutionMiddleware
{
private readonly ActivityMiddlewareDelegate _next;
- private readonly ISystemClock _clock;
+ private readonly ISystemClock _systemClock;
private readonly ILogger _logger;
- public ActivityInvokerMiddleware(ActivityMiddlewareDelegate next, ISystemClock clock, ILogger logger)
+ public ActivityInvokerMiddleware(ActivityMiddlewareDelegate next, ISystemClock systemClock, ILogger logger)
{
_next = next;
- _clock = clock;
+ _systemClock = systemClock;
_logger = logger;
}
diff --git a/src/modules/Elsa.Workflows.Core/Services/IActivityPortResolver.cs b/src/modules/Elsa.Workflows.Core/Services/IActivityPortResolver.cs
index 59ad0f701..de834746b 100644
--- a/src/modules/Elsa.Workflows.Core/Services/IActivityPortResolver.cs
+++ b/src/modules/Elsa.Workflows.Core/Services/IActivityPortResolver.cs
@@ -1,5 +1,3 @@
-using System.Reflection;
-
namespace Elsa.Workflows.Core.Services;
///
diff --git a/src/modules/Elsa.Workflows.Management/Features/WorkflowManagementFeature.cs b/src/modules/Elsa.Workflows.Management/Features/WorkflowManagementFeature.cs
index 2c1aca117..91f831753 100644
--- a/src/modules/Elsa.Workflows.Management/Features/WorkflowManagementFeature.cs
+++ b/src/modules/Elsa.Workflows.Management/Features/WorkflowManagementFeature.cs
@@ -1,3 +1,4 @@
+using Elsa.Common.Features;
using Elsa.Expressions.Services;
using Elsa.Features.Abstractions;
using Elsa.Features.Attributes;
@@ -18,6 +19,7 @@ using Microsoft.Extensions.DependencyInjection;
namespace Elsa.Workflows.Management.Features;
[DependsOn(typeof(MediatorFeature))]
+[DependsOn(typeof(SystemClockFeature))]
[DependsOn(typeof(WorkflowsFeature))]
[DependsOn(typeof(WorkflowPersistenceFeature))]
public class WorkflowManagementFeature : FeatureBase
diff --git a/src/modules/Elsa.Workflows.Management/Implementations/WorkflowDefinitionPublisher.cs b/src/modules/Elsa.Workflows.Management/Implementations/WorkflowDefinitionPublisher.cs
index 89f1b2e8b..4907c4b18 100644
--- a/src/modules/Elsa.Workflows.Management/Implementations/WorkflowDefinitionPublisher.cs
+++ b/src/modules/Elsa.Workflows.Management/Implementations/WorkflowDefinitionPublisher.cs
@@ -1,4 +1,5 @@
using System.Text.Json;
+using Elsa.Common.Services;
using Elsa.Mediator.Services;
using Elsa.Persistence.Common.Models;
using Elsa.Workflows.Core.Activities;
@@ -8,7 +9,6 @@ using Elsa.Workflows.Management.Materializers;
using Elsa.Workflows.Management.Notifications;
using Elsa.Workflows.Management.Services;
using Elsa.Workflows.Persistence.Entities;
-using Elsa.Workflows.Persistence.Models;
using Elsa.Workflows.Persistence.Services;
namespace Elsa.Workflows.Management.Implementations
diff --git a/src/modules/Elsa.Workflows.Persistence.EntityFrameworkCore/Features/EFCoreWorkflowPersistenceFeature.cs b/src/modules/Elsa.Workflows.Persistence.EntityFrameworkCore/Features/EFCoreWorkflowPersistenceFeature.cs
index 2e0365462..f32f8e132 100644
--- a/src/modules/Elsa.Workflows.Persistence.EntityFrameworkCore/Features/EFCoreWorkflowPersistenceFeature.cs
+++ b/src/modules/Elsa.Workflows.Persistence.EntityFrameworkCore/Features/EFCoreWorkflowPersistenceFeature.cs
@@ -1,3 +1,4 @@
+using Elsa.Features.Attributes;
using Elsa.Features.Services;
using Elsa.Persistence.EntityFrameworkCore.Common.Abstractions;
using Elsa.Persistence.EntityFrameworkCore.Common.Services;
@@ -9,6 +10,7 @@ using Microsoft.Extensions.DependencyInjection;
namespace Elsa.Workflows.Persistence.EntityFrameworkCore.Features;
+[DependsOn(typeof(WorkflowPersistenceFeature))]
public class EFCoreWorkflowPersistenceFeature : EFCorePersistenceFeature
{
public EFCoreWorkflowPersistenceFeature(IModule module) : base(module)
diff --git a/src/modules/Elsa.Workflows.Persistence.EntityFrameworkCore/Implementations/EFCoreWorkflowDefinitionStore.cs b/src/modules/Elsa.Workflows.Persistence.EntityFrameworkCore/Implementations/EFCoreWorkflowDefinitionStore.cs
index edb0c385c..deacdc851 100644
--- a/src/modules/Elsa.Workflows.Persistence.EntityFrameworkCore/Implementations/EFCoreWorkflowDefinitionStore.cs
+++ b/src/modules/Elsa.Workflows.Persistence.EntityFrameworkCore/Implementations/EFCoreWorkflowDefinitionStore.cs
@@ -4,7 +4,6 @@ using Elsa.Persistence.Common.Models;
using Elsa.Persistence.EntityFrameworkCore.Common.Extensions;
using Elsa.Persistence.EntityFrameworkCore.Common.Services;
using Elsa.Workflows.Persistence.Entities;
-using Elsa.Workflows.Persistence.Extensions;
using Elsa.Workflows.Persistence.Models;
using Elsa.Workflows.Persistence.Services;
diff --git a/src/modules/Elsa.Workflows.Persistence/Extensions/WorkflowExtensions.cs b/src/modules/Elsa.Workflows.Persistence/Extensions/WorkflowExtensions.cs
index b35018460..039c38577 100644
--- a/src/modules/Elsa.Workflows.Persistence/Extensions/WorkflowExtensions.cs
+++ b/src/modules/Elsa.Workflows.Persistence/Extensions/WorkflowExtensions.cs
@@ -1,6 +1,5 @@
using Elsa.Persistence.Common.Models;
using Elsa.Workflows.Core.Models;
-using Elsa.Workflows.Persistence.Models;
namespace Elsa.Workflows.Persistence.Extensions;
diff --git a/src/modules/Elsa.Workflows.Persistence/Implementations/MemoryWorkflowDefinitionStore.cs b/src/modules/Elsa.Workflows.Persistence/Implementations/MemoryWorkflowDefinitionStore.cs
index 546de5fff..b896a05a4 100644
--- a/src/modules/Elsa.Workflows.Persistence/Implementations/MemoryWorkflowDefinitionStore.cs
+++ b/src/modules/Elsa.Workflows.Persistence/Implementations/MemoryWorkflowDefinitionStore.cs
@@ -2,7 +2,6 @@ using Elsa.Persistence.Common.Extensions;
using Elsa.Persistence.Common.Implementations;
using Elsa.Persistence.Common.Models;
using Elsa.Workflows.Persistence.Entities;
-using Elsa.Workflows.Persistence.Extensions;
using Elsa.Workflows.Persistence.Models;
using Elsa.Workflows.Persistence.Services;
diff --git a/src/modules/Elsa.Workflows.Runtime/Activities/DispatchWorkflow.cs b/src/modules/Elsa.Workflows.Runtime/Activities/DispatchWorkflow.cs
index bd46568f2..b02cde09f 100644
--- a/src/modules/Elsa.Workflows.Runtime/Activities/DispatchWorkflow.cs
+++ b/src/modules/Elsa.Workflows.Runtime/Activities/DispatchWorkflow.cs
@@ -2,7 +2,6 @@ using Elsa.Persistence.Common.Models;
using Elsa.Workflows.Core;
using Elsa.Workflows.Core.Attributes;
using Elsa.Workflows.Core.Models;
-using Elsa.Workflows.Persistence.Models;
using Elsa.Workflows.Runtime.Services;
using Microsoft.Extensions.Logging;
diff --git a/src/modules/Elsa.Workflows.Runtime/Extensions/DependencyInjectionExtensions.cs b/src/modules/Elsa.Workflows.Runtime/Extensions/DependencyInjectionExtensions.cs
index 7ec7dfdbb..bd82c7f41 100644
--- a/src/modules/Elsa.Workflows.Runtime/Extensions/DependencyInjectionExtensions.cs
+++ b/src/modules/Elsa.Workflows.Runtime/Extensions/DependencyInjectionExtensions.cs
@@ -1,4 +1,3 @@
-using System.Threading.Channels;
using Elsa.Features.Services;
using Elsa.Workflows.Runtime.Features;
using Elsa.Workflows.Runtime.Services;
@@ -13,17 +12,7 @@ public static class DependencyInjectionExtensions
module.Configure(configure);
return module;
}
-
- public static IServiceCollection CreateChannel(this IServiceCollection services) =>
- services
- .AddSingleton(CreateChannel())
- .AddSingleton(CreateChannelReader)
- .AddSingleton(CreateChannelWriter);
-
- private static Channel CreateChannel() => Channel.CreateUnbounded(new UnboundedChannelOptions());
- private static ChannelReader CreateChannelReader(IServiceProvider serviceProvider) => serviceProvider.GetRequiredService>().Reader;
- private static ChannelWriter CreateChannelWriter(IServiceProvider serviceProvider) => serviceProvider.GetRequiredService>().Writer;
-
+
public static IServiceCollection AddWorkflowDefinitionProvider(this IServiceCollection services) where T : class, IWorkflowDefinitionProvider => services.AddSingleton();
public static IServiceCollection AddStimulusHandler(this IServiceCollection services) where T : class, IStimulusHandler => services.AddSingleton();
public static IServiceCollection AddInstructionInterpreter(this IServiceCollection services) where T : class, IWorkflowInstructionInterpreter => services.AddSingleton();
diff --git a/src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs b/src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs
index d643a9644..7659715ba 100644
--- a/src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs
+++ b/src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs
@@ -1,4 +1,6 @@
+using Elsa.Common.Features;
using Elsa.Features.Abstractions;
+using Elsa.Features.Attributes;
using Elsa.Features.Services;
using Elsa.Mediator.Extensions;
using Elsa.Workflows.Core.Services;
@@ -15,6 +17,7 @@ using Microsoft.Extensions.DependencyInjection;
namespace Elsa.Workflows.Runtime.Features;
+[DependsOn(typeof(SystemClockFeature))]
public class WorkflowRuntimeFeature : FeatureBase
{
public WorkflowRuntimeFeature(IModule module) : base(module)
diff --git a/src/modules/Elsa.Workflows.Runtime/HostedServices/PopulateWorkflowDefinitionStore.cs b/src/modules/Elsa.Workflows.Runtime/HostedServices/PopulateWorkflowDefinitionStore.cs
index 57d583478..d9d0b6ba9 100644
--- a/src/modules/Elsa.Workflows.Runtime/HostedServices/PopulateWorkflowDefinitionStore.cs
+++ b/src/modules/Elsa.Workflows.Runtime/HostedServices/PopulateWorkflowDefinitionStore.cs
@@ -1,7 +1,6 @@
using Elsa.Persistence.Common.Models;
using Elsa.Workflows.Core.Models;
using Elsa.Workflows.Persistence.Entities;
-using Elsa.Workflows.Persistence.Models;
using Elsa.Workflows.Persistence.Services;
using Elsa.Workflows.Runtime.Services;
using Microsoft.Extensions.Hosting;
diff --git a/src/modules/Elsa.Workflows.Runtime/Implementations/DefaultWorkflowInvoker.cs b/src/modules/Elsa.Workflows.Runtime/Implementations/DefaultWorkflowInvoker.cs
index fe3ec20ef..eba1ff4f3 100644
--- a/src/modules/Elsa.Workflows.Runtime/Implementations/DefaultWorkflowInvoker.cs
+++ b/src/modules/Elsa.Workflows.Runtime/Implementations/DefaultWorkflowInvoker.cs
@@ -3,7 +3,6 @@ using Elsa.Workflows.Core.Models;
using Elsa.Workflows.Core.Services;
using Elsa.Workflows.Core.State;
using Elsa.Workflows.Persistence.Entities;
-using Elsa.Workflows.Persistence.Models;
using Elsa.Workflows.Persistence.Services;
using Elsa.Workflows.Runtime.Models;
using Elsa.Workflows.Runtime.Services;
diff --git a/src/modules/Elsa.Workflows.Runtime/Implementations/WorkflowInstanceFactory.cs b/src/modules/Elsa.Workflows.Runtime/Implementations/WorkflowInstanceFactory.cs
index 4d4a036c1..3b3a6c4f9 100644
--- a/src/modules/Elsa.Workflows.Runtime/Implementations/WorkflowInstanceFactory.cs
+++ b/src/modules/Elsa.Workflows.Runtime/Implementations/WorkflowInstanceFactory.cs
@@ -1,9 +1,9 @@
+using Elsa.Common.Services;
using Elsa.Persistence.Common.Models;
using Elsa.Workflows.Core.Models;
using Elsa.Workflows.Core.Services;
using Elsa.Workflows.Core.State;
using Elsa.Workflows.Persistence.Entities;
-using Elsa.Workflows.Persistence.Models;
using Elsa.Workflows.Persistence.Services;
using Elsa.Workflows.Runtime.Services;
diff --git a/src/modules/Elsa.Workflows.Runtime/Implementations/WorkflowService.cs b/src/modules/Elsa.Workflows.Runtime/Implementations/WorkflowService.cs
index 6c1b546f1..61b19a0b1 100644
--- a/src/modules/Elsa.Workflows.Runtime/Implementations/WorkflowService.cs
+++ b/src/modules/Elsa.Workflows.Runtime/Implementations/WorkflowService.cs
@@ -1,7 +1,6 @@
using Elsa.Persistence.Common.Models;
using Elsa.Workflows.Core.Models;
using Elsa.Workflows.Core.Services;
-using Elsa.Workflows.Persistence.Models;
using Elsa.Workflows.Runtime.Models;
using Elsa.Workflows.Runtime.Services;
diff --git a/src/modules/Elsa.Workflows.Runtime/Interpreters/ResumeWorkflowInstructionInterpreter.cs b/src/modules/Elsa.Workflows.Runtime/Interpreters/ResumeWorkflowInstructionInterpreter.cs
index 2959b911c..ee11c6523 100644
--- a/src/modules/Elsa.Workflows.Runtime/Interpreters/ResumeWorkflowInstructionInterpreter.cs
+++ b/src/modules/Elsa.Workflows.Runtime/Interpreters/ResumeWorkflowInstructionInterpreter.cs
@@ -2,7 +2,6 @@ using Elsa.Persistence.Common.Models;
using Elsa.Workflows.Core.Models;
using Elsa.Workflows.Core.Services;
using Elsa.Workflows.Persistence.Entities;
-using Elsa.Workflows.Persistence.Models;
using Elsa.Workflows.Persistence.Services;
using Elsa.Workflows.Runtime.Abstractions;
using Elsa.Workflows.Runtime.Models;
diff --git a/src/modules/Elsa.Workflows.Runtime/Interpreters/TriggerWorkflowInstructionInterpreter.cs b/src/modules/Elsa.Workflows.Runtime/Interpreters/TriggerWorkflowInstructionInterpreter.cs
index 0b7fd4f09..ad1f4f61f 100644
--- a/src/modules/Elsa.Workflows.Runtime/Interpreters/TriggerWorkflowInstructionInterpreter.cs
+++ b/src/modules/Elsa.Workflows.Runtime/Interpreters/TriggerWorkflowInstructionInterpreter.cs
@@ -1,6 +1,5 @@
using Elsa.Persistence.Common.Models;
using Elsa.Workflows.Persistence.Entities;
-using Elsa.Workflows.Persistence.Models;
using Elsa.Workflows.Persistence.Services;
using Elsa.Workflows.Runtime.Abstractions;
using Elsa.Workflows.Runtime.Models;
diff --git a/src/modules/Elsa.Workflows.Runtime/Middleware/PersistWorkflowInstanceMiddleware.cs b/src/modules/Elsa.Workflows.Runtime/Middleware/PersistWorkflowInstanceMiddleware.cs
index 7f5de318e..4428f60d1 100644
--- a/src/modules/Elsa.Workflows.Runtime/Middleware/PersistWorkflowInstanceMiddleware.cs
+++ b/src/modules/Elsa.Workflows.Runtime/Middleware/PersistWorkflowInstanceMiddleware.cs
@@ -1,3 +1,4 @@
+using Elsa.Common.Services;
using Elsa.Mediator.Services;
using Elsa.Workflows.Core.Helpers;
using Elsa.Workflows.Core.Models;
@@ -22,35 +23,32 @@ public class PersistWorkflowInstanceMiddleware : WorkflowExecutionMiddleware
private readonly IWorkflowInstanceStore _workflowInstanceStore;
private readonly IWorkflowBookmarkStore _bookmarkStore;
- private readonly IRequestSender _requestSender;
private readonly IEventPublisher _eventPublisher;
private readonly IWorkflowStateSerializer _workflowStateSerializer;
private readonly IStorageDriverManager _storageDriverManager;
private readonly IBookmarkManager _bookmarkManager;
private readonly IIdentityGenerator _identityGenerator;
- private readonly ISystemClock _clock;
+ private readonly ISystemClock _systemClock;
public PersistWorkflowInstanceMiddleware(
WorkflowMiddlewareDelegate next,
IWorkflowInstanceStore workflowInstanceStore,
IWorkflowBookmarkStore bookmarkStore,
- IRequestSender requestSender,
IEventPublisher eventPublisher,
IBookmarkManager bookmarkManager,
IWorkflowStateSerializer workflowStateSerializer,
IStorageDriverManager storageDriverManager,
IIdentityGenerator identityGenerator,
- ISystemClock clock) : base(next)
+ ISystemClock systemClock) : base(next)
{
_workflowInstanceStore = workflowInstanceStore;
_bookmarkStore = bookmarkStore;
- _requestSender = requestSender;
_eventPublisher = eventPublisher;
_bookmarkManager = bookmarkManager;
_workflowStateSerializer = workflowStateSerializer;
_storageDriverManager = storageDriverManager;
_identityGenerator = identityGenerator;
- _clock = clock;
+ _systemClock = systemClock;
}
public override async ValueTask InvokeAsync(WorkflowExecutionContext context)
@@ -60,7 +58,7 @@ public class PersistWorkflowInstanceMiddleware : WorkflowExecutionMiddleware
var (definitionId, version, definitionVersionId) = workflow.Identity;
var existingWorkflowInstance = await _workflowInstanceStore.FindByIdAsync(context.Id, cancellationToken);
var workflowInstanceName = default(string?);
- var now = _clock.UtcNow;
+ var now = _systemClock.UtcNow;
// Get the workflow instance name, if any (could be provided by previously executed middleware).
if (context.TransientProperties.TryGetValue(WorkflowInstanceNameKey, out var name))
diff --git a/src/modules/Elsa.Workflows.Runtime/Models/DispatchWorkflowDefinitionRequest.cs b/src/modules/Elsa.Workflows.Runtime/Models/DispatchWorkflowDefinitionRequest.cs
index 80e93a359..37f3de809 100644
--- a/src/modules/Elsa.Workflows.Runtime/Models/DispatchWorkflowDefinitionRequest.cs
+++ b/src/modules/Elsa.Workflows.Runtime/Models/DispatchWorkflowDefinitionRequest.cs
@@ -1,5 +1,4 @@
using Elsa.Persistence.Common.Models;
-using Elsa.Workflows.Persistence.Models;
namespace Elsa.Workflows.Runtime.Models;
diff --git a/src/modules/Elsa.Workflows.Runtime/Models/InvokeWorkflowDefinitionRequest.cs b/src/modules/Elsa.Workflows.Runtime/Models/InvokeWorkflowDefinitionRequest.cs
index 49762f117..8213d4a3c 100644
--- a/src/modules/Elsa.Workflows.Runtime/Models/InvokeWorkflowDefinitionRequest.cs
+++ b/src/modules/Elsa.Workflows.Runtime/Models/InvokeWorkflowDefinitionRequest.cs
@@ -1,5 +1,4 @@
using Elsa.Persistence.Common.Models;
-using Elsa.Workflows.Persistence.Models;
namespace Elsa.Workflows.Runtime.Models;
diff --git a/src/modules/Elsa.Workflows.Runtime/Services/IWorkflowInstanceFactory.cs b/src/modules/Elsa.Workflows.Runtime/Services/IWorkflowInstanceFactory.cs
index 2ce704d55..7b01982ad 100644
--- a/src/modules/Elsa.Workflows.Runtime/Services/IWorkflowInstanceFactory.cs
+++ b/src/modules/Elsa.Workflows.Runtime/Services/IWorkflowInstanceFactory.cs
@@ -1,7 +1,6 @@
using Elsa.Persistence.Common.Models;
using Elsa.Workflows.Core.Models;
using Elsa.Workflows.Persistence.Entities;
-using Elsa.Workflows.Persistence.Models;
namespace Elsa.Workflows.Runtime.Services;
diff --git a/src/modules/Elsa.Workflows.Runtime/Services/IWorkflowService.cs b/src/modules/Elsa.Workflows.Runtime/Services/IWorkflowService.cs
index d7debb8fb..a30399291 100644
--- a/src/modules/Elsa.Workflows.Runtime/Services/IWorkflowService.cs
+++ b/src/modules/Elsa.Workflows.Runtime/Services/IWorkflowService.cs
@@ -1,7 +1,5 @@
using Elsa.Persistence.Common.Models;
using Elsa.Workflows.Core.Models;
-using Elsa.Workflows.Persistence.Models;
-using Elsa.Workflows.Runtime.Attributes;
using Elsa.Workflows.Runtime.Models;
namespace Elsa.Workflows.Runtime.Services;
diff --git a/src/modules/Elsa.Workflows.Runtime/WorkflowProviders/ClrWorkflowDefinitionProvider.cs b/src/modules/Elsa.Workflows.Runtime/WorkflowProviders/ClrWorkflowDefinitionProvider.cs
index 88b74d357..91b9c2a77 100644
--- a/src/modules/Elsa.Workflows.Runtime/WorkflowProviders/ClrWorkflowDefinitionProvider.cs
+++ b/src/modules/Elsa.Workflows.Runtime/WorkflowProviders/ClrWorkflowDefinitionProvider.cs
@@ -1,4 +1,5 @@
using System.Text.Json;
+using Elsa.Common.Services;
using Elsa.Workflows.Management.Materializers;
using Elsa.Workflows.Core.Serialization;
using Elsa.Workflows.Core.Services;
@@ -58,7 +59,7 @@ public class ClrWorkflowDefinitionProvider : IWorkflowDefinitionProvider
await workflowBuilder.BuildAsync(builder, cancellationToken);
var workflow = builder.BuildWorkflow();
- _identityGraphService.AssignIdentitiesAsync(workflow);
+ await _identityGraphService.AssignIdentitiesAsync(workflow, cancellationToken);
var workflowJson = JsonSerializer.Serialize(workflow.Root, _serializerOptionsProvider.CreatePersistenceOptions());
var materializerContext = new ClrWorkflowMaterializerContext(workflowBuilder.GetType());
diff --git a/src/samples/aspnet/Elsa.Samples.Web1/Elsa.Samples.Web1.csproj b/src/samples/aspnet/Elsa.Samples.Web1/Elsa.Samples.Web1.csproj
index 043937f79..cd704524f 100644
--- a/src/samples/aspnet/Elsa.Samples.Web1/Elsa.Samples.Web1.csproj
+++ b/src/samples/aspnet/Elsa.Samples.Web1/Elsa.Samples.Web1.csproj
@@ -8,7 +8,7 @@
-
+
diff --git a/src/samples/aspnet/Elsa.Samples.Web1/Program.cs b/src/samples/aspnet/Elsa.Samples.Web1/Program.cs
index 0b8001985..cf188e66f 100644
--- a/src/samples/aspnet/Elsa.Samples.Web1/Program.cs
+++ b/src/samples/aspnet/Elsa.Samples.Web1/Program.cs
@@ -1,11 +1,9 @@
using Elsa.AspNetCore.Extensions;
using Elsa.Extensions;
-using Elsa.Hangfire.Implementations;
using Elsa.Http.Extensions;
using Elsa.JavaScript.Extensions;
using Elsa.Jobs.Extensions;
using Elsa.Liquid.Extensions;
-using Elsa.Quartz.Implementations;
using Elsa.Samples.Web1.Workflows;
using Elsa.Scheduling.Extensions;
using Elsa.WorkflowContexts.Extensions;
@@ -48,6 +46,8 @@ services
runtime.Workflows.Add();
runtime.Workflows.Add();
})
+ .UseJobs()
+ .UseScheduling()
.UseWorkflowApiEndpoints()
.UseJavaScript()
.UseLiquid()
@@ -55,10 +55,6 @@ services
.UseMvc()
);
-services
- .AddJobServices(new QuartzJobSchedulerProvider(), new HangfireJobQueueProvider())
- .AddSchedulingServices();
-
// Add controller services. The below technique allows full control over what controllers get added from which assemblies.
// It is even possible to add individual controllers this way using a custom TypesPart.
// If you want to include all controllers
diff --git a/src/samples/aspnet/Elsa.Samples.Web1/Workflows/DelayWorkflow.cs b/src/samples/aspnet/Elsa.Samples.Web1/Workflows/DelayWorkflow.cs
index 7163f3be2..1cdd173c5 100644
--- a/src/samples/aspnet/Elsa.Samples.Web1/Workflows/DelayWorkflow.cs
+++ b/src/samples/aspnet/Elsa.Samples.Web1/Workflows/DelayWorkflow.cs
@@ -1,3 +1,4 @@
+using Elsa.Common.Services;
using Elsa.Scheduling.Activities;
using Elsa.Workflows.Core.Activities;
using Elsa.Workflows.Core.Services;
diff --git a/src/samples/aspnet/Elsa.Samples.Web1/Workflows/HeartbeatWorkflow.cs b/src/samples/aspnet/Elsa.Samples.Web1/Workflows/HeartbeatWorkflow.cs
index bed2dbf32..41e2842c7 100644
--- a/src/samples/aspnet/Elsa.Samples.Web1/Workflows/HeartbeatWorkflow.cs
+++ b/src/samples/aspnet/Elsa.Samples.Web1/Workflows/HeartbeatWorkflow.cs
@@ -1,4 +1,5 @@
using System;
+using Elsa.Common.Services;
using Elsa.Scheduling.Activities;
using Elsa.Workflows.Core.Activities;
using Elsa.Workflows.Core.Services;
diff --git a/src/samples/aspnet/Elsa.Samples.Web1/Workflows/StartAtBookmarkWorkflow.cs b/src/samples/aspnet/Elsa.Samples.Web1/Workflows/StartAtBookmarkWorkflow.cs
index 094867a0d..b5f26133c 100644
--- a/src/samples/aspnet/Elsa.Samples.Web1/Workflows/StartAtBookmarkWorkflow.cs
+++ b/src/samples/aspnet/Elsa.Samples.Web1/Workflows/StartAtBookmarkWorkflow.cs
@@ -1,3 +1,4 @@
+using Elsa.Common.Services;
using Elsa.Scheduling.Activities;
using Elsa.Workflows.Core.Activities;
using Elsa.Workflows.Core.Services;
diff --git a/src/samples/aspnet/Elsa.Samples.Web1/Workflows/StartAtTriggerWorkflow.cs b/src/samples/aspnet/Elsa.Samples.Web1/Workflows/StartAtTriggerWorkflow.cs
index 142e2269b..0f1395caa 100644
--- a/src/samples/aspnet/Elsa.Samples.Web1/Workflows/StartAtTriggerWorkflow.cs
+++ b/src/samples/aspnet/Elsa.Samples.Web1/Workflows/StartAtTriggerWorkflow.cs
@@ -1,4 +1,5 @@
using System;
+using Elsa.Common.Services;
using Elsa.Scheduling.Activities;
using Elsa.Workflows.Core.Activities;
using Elsa.Workflows.Core.Services;
diff --git a/src/samples/aspnet/Elsa.Samples.Web2/Elsa.Samples.Web2.csproj b/src/samples/aspnet/Elsa.Samples.Web2/Elsa.Samples.Web2.csproj
index 148f5f9a6..6a7b66f3c 100644
--- a/src/samples/aspnet/Elsa.Samples.Web2/Elsa.Samples.Web2.csproj
+++ b/src/samples/aspnet/Elsa.Samples.Web2/Elsa.Samples.Web2.csproj
@@ -7,7 +7,7 @@
-
+
diff --git a/src/samples/aspnet/Elsa.Samples.Web2/Program.cs b/src/samples/aspnet/Elsa.Samples.Web2/Program.cs
index 4b62ba47d..86d9b2c24 100644
--- a/src/samples/aspnet/Elsa.Samples.Web2/Program.cs
+++ b/src/samples/aspnet/Elsa.Samples.Web2/Program.cs
@@ -1,12 +1,10 @@
using Elsa.AspNetCore.Extensions;
using Elsa.Extensions;
-using Elsa.Hangfire.Implementations;
using Elsa.Http;
using Elsa.Http.Extensions;
using Elsa.JavaScript.Activities;
using Elsa.Jobs.Extensions;
using Elsa.ProtoActor.Extensions;
-using Elsa.Quartz.Implementations;
using Elsa.Scheduling.Activities;
using Elsa.Scheduling.Extensions;
using Elsa.Workflows.Api.Extensions;
@@ -40,15 +38,13 @@ services
.AddActivity()
.AddActivity()
.AddActivity())
+ .UseJobs()
+ .UseScheduling()
.UseWorkflowApiEndpoints()
.UseHttp()
.UseMvc()
);
-services
- .AddJobServices(new QuartzJobSchedulerProvider(), new HangfireJobQueueProvider())
- .AddSchedulingServices();
-
// Testing only: allow client app to connect from anywhere.
services.AddCors(cors => cors.AddDefaultPolicy(policy => policy.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin()));
diff --git a/src/samples/aspnet/Elsa.Samples.Web3/Elsa.Samples.Web3.csproj b/src/samples/aspnet/Elsa.Samples.Web3/Elsa.Samples.Web3.csproj
index f73ca85b4..b8c9512b2 100644
--- a/src/samples/aspnet/Elsa.Samples.Web3/Elsa.Samples.Web3.csproj
+++ b/src/samples/aspnet/Elsa.Samples.Web3/Elsa.Samples.Web3.csproj
@@ -9,7 +9,7 @@
-
+
diff --git a/src/samples/aspnet/Elsa.Samples.Web3/Program.cs b/src/samples/aspnet/Elsa.Samples.Web3/Program.cs
index 1912eeb40..cd0783163 100644
--- a/src/samples/aspnet/Elsa.Samples.Web3/Program.cs
+++ b/src/samples/aspnet/Elsa.Samples.Web3/Program.cs
@@ -1,11 +1,9 @@
using Elsa.AspNetCore.Extensions;
using Elsa.Extensions;
-using Elsa.Hangfire.Implementations;
using Elsa.Http;
using Elsa.Http.Extensions;
using Elsa.JavaScript.Activities;
using Elsa.Jobs.Extensions;
-using Elsa.Quartz.Implementations;
using Elsa.Scheduling.Activities;
using Elsa.Scheduling.Extensions;
using Elsa.Workflows.Api.Extensions;
@@ -31,15 +29,13 @@ services
.AddActivity()
.AddActivity()
.AddActivity())
+ .UseJobs()
+ .UseScheduling()
.UseWorkflowApiEndpoints()
.UseHttp()
.UseMvc()
);
-services
- .AddJobServices(new QuartzJobSchedulerProvider(), new HangfireJobQueueProvider())
- .AddSchedulingServices();
-
// Razor Pages.
services.AddRazorPages();