diff --git a/Directory.Packages.props b/Directory.Packages.props
index ea39e0d4..0ae482e5 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -141,13 +141,13 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
@@ -243,4 +243,4 @@
-
\ No newline at end of file
+
diff --git a/src/modules/scheduling/Elsa.Scheduling.Quartz.EFCore.MySql/ShellFeatures/QuartzMySqlFeature.cs b/src/modules/scheduling/Elsa.Scheduling.Quartz.EFCore.MySql/ShellFeatures/QuartzMySqlFeature.cs
index 2af0f17b..ecb4c03a 100644
--- a/src/modules/scheduling/Elsa.Scheduling.Quartz.EFCore.MySql/ShellFeatures/QuartzMySqlFeature.cs
+++ b/src/modules/scheduling/Elsa.Scheduling.Quartz.EFCore.MySql/ShellFeatures/QuartzMySqlFeature.cs
@@ -35,8 +35,7 @@ public void ConfigureServices(IServiceCollection services)
else
services.AddDbContextFactory(Configure);
- services.AddTransient(sp =>
- new EfCoreMigrationHandler(sp.GetRequiredService>()));
+ services.AddShellInitializer(LifecyclePhase.Prepare, order: 100);
services.AddQuartz(quartz =>
{
diff --git a/src/modules/scheduling/Elsa.Scheduling.Quartz.EFCore.PostgreSql/ShellFeatures/QuartzPostgreSqlFeature.cs b/src/modules/scheduling/Elsa.Scheduling.Quartz.EFCore.PostgreSql/ShellFeatures/QuartzPostgreSqlFeature.cs
index c2b9ba79..52e2eb0d 100644
--- a/src/modules/scheduling/Elsa.Scheduling.Quartz.EFCore.PostgreSql/ShellFeatures/QuartzPostgreSqlFeature.cs
+++ b/src/modules/scheduling/Elsa.Scheduling.Quartz.EFCore.PostgreSql/ShellFeatures/QuartzPostgreSqlFeature.cs
@@ -35,8 +35,7 @@ public void ConfigureServices(IServiceCollection services)
else
services.AddDbContextFactory(Configure);
- services.AddTransient(sp =>
- new EfCoreMigrationHandler(sp.GetRequiredService>()));
+ services.AddShellInitializer(LifecyclePhase.Prepare, order: 100);
services.AddQuartz(quartz =>
{
diff --git a/src/modules/scheduling/Elsa.Scheduling.Quartz.EFCore.SqlServer/ShellFeatures/QuartzSqlServerFeature.cs b/src/modules/scheduling/Elsa.Scheduling.Quartz.EFCore.SqlServer/ShellFeatures/QuartzSqlServerFeature.cs
index 538385a6..87943402 100644
--- a/src/modules/scheduling/Elsa.Scheduling.Quartz.EFCore.SqlServer/ShellFeatures/QuartzSqlServerFeature.cs
+++ b/src/modules/scheduling/Elsa.Scheduling.Quartz.EFCore.SqlServer/ShellFeatures/QuartzSqlServerFeature.cs
@@ -35,8 +35,7 @@ public void ConfigureServices(IServiceCollection services)
else
services.AddDbContextFactory(Configure);
- services.AddTransient(sp =>
- new EfCoreMigrationHandler(sp.GetRequiredService>()));
+ services.AddShellInitializer(LifecyclePhase.Prepare, order: 100);
// AddQuartz is additive — layers the persistent store onto the base
// AddQuartz call already made by QuartzFeature (which ran first via DependsOn).
diff --git a/src/modules/scheduling/Elsa.Scheduling.Quartz.EFCore.Sqlite/ShellFeatures/QuartzSqliteFeature.cs b/src/modules/scheduling/Elsa.Scheduling.Quartz.EFCore.Sqlite/ShellFeatures/QuartzSqliteFeature.cs
index ce3263cd..e16ab026 100644
--- a/src/modules/scheduling/Elsa.Scheduling.Quartz.EFCore.Sqlite/ShellFeatures/QuartzSqliteFeature.cs
+++ b/src/modules/scheduling/Elsa.Scheduling.Quartz.EFCore.Sqlite/ShellFeatures/QuartzSqliteFeature.cs
@@ -38,9 +38,7 @@ public void ConfigureServices(IServiceCollection services)
else
services.AddDbContextFactory(Configure);
- services.AddTransient(sp =>
- new EfCoreMigrationHandler(
- sp.GetRequiredService>()));
+ services.AddShellInitializer(LifecyclePhase.Prepare, order: 100);
}
public void PostConfigureServices(IServiceCollection services)
diff --git a/src/modules/scheduling/Elsa.Scheduling.Quartz/ShellFeatures/QuartzShellLifecycleHandler.cs b/src/modules/scheduling/Elsa.Scheduling.Quartz/ShellFeatures/QuartzShellLifecycleHandler.cs
index 843e409b..66fb2e4a 100644
--- a/src/modules/scheduling/Elsa.Scheduling.Quartz/ShellFeatures/QuartzShellLifecycleHandler.cs
+++ b/src/modules/scheduling/Elsa.Scheduling.Quartz/ShellFeatures/QuartzShellLifecycleHandler.cs
@@ -15,6 +15,7 @@ namespace Elsa.Scheduling.Quartz.ShellFeatures;
/// so the AwaitApplicationStarted deferral logic from QuartzHostedService
/// is intentionally omitted — it is irrelevant in this context.
///
+[LifecycleOrder(LifecyclePhase.Start, 100)]
public class QuartzShellLifecycleHandler(
IQuartzSchedulerFactory schedulerFactory,
IHostApplicationLifetime appLifetime,
diff --git a/test/modules/scheduling/Elsa.Scheduling.Quartz.UnitTests/Elsa.Scheduling.Quartz.UnitTests.csproj b/test/modules/scheduling/Elsa.Scheduling.Quartz.UnitTests/Elsa.Scheduling.Quartz.UnitTests.csproj
index c9bdbb85..c3e2a940 100644
--- a/test/modules/scheduling/Elsa.Scheduling.Quartz.UnitTests/Elsa.Scheduling.Quartz.UnitTests.csproj
+++ b/test/modules/scheduling/Elsa.Scheduling.Quartz.UnitTests/Elsa.Scheduling.Quartz.UnitTests.csproj
@@ -2,6 +2,10 @@
+
+
+
+
diff --git a/test/modules/scheduling/Elsa.Scheduling.Quartz.UnitTests/ShellFeatures/QuartzFeatureTests.cs b/test/modules/scheduling/Elsa.Scheduling.Quartz.UnitTests/ShellFeatures/QuartzFeatureTests.cs
index 5210ef2d..51399a8e 100644
--- a/test/modules/scheduling/Elsa.Scheduling.Quartz.UnitTests/ShellFeatures/QuartzFeatureTests.cs
+++ b/test/modules/scheduling/Elsa.Scheduling.Quartz.UnitTests/ShellFeatures/QuartzFeatureTests.cs
@@ -1,7 +1,12 @@
using CShells.Features;
using CShells.Lifecycle;
+using Elsa.Scheduling.Quartz.EFCore.MySql.ShellFeatures;
+using Elsa.Scheduling.Quartz.EFCore.PostgreSql.ShellFeatures;
+using Elsa.Scheduling.Quartz.EFCore.SqlServer.ShellFeatures;
+using Elsa.Scheduling.Quartz.EFCore.Sqlite.ShellFeatures;
using Elsa.Scheduling.Quartz.ShellFeatures;
using Microsoft.Extensions.DependencyInjection;
+using System.Reflection;
namespace Elsa.Scheduling.Quartz.UnitTests.ShellFeatures;
@@ -26,6 +31,42 @@ public void SchedulerInitializer_IsRegisteredDuringPostConfigure()
Assert.NotNull(initializerRegistrations[1].ImplementationFactory);
}
+ [Fact]
+ public void SchedulerInitializer_RunsInStartPhase()
+ {
+ var order = typeof(QuartzShellLifecycleHandler).GetCustomAttribute();
+
+ Assert.NotNull(order);
+ Assert.Equal(LifecyclePhase.Start, order.Phase);
+ Assert.Equal(100, order.Order);
+ }
+
+ [Theory]
+ [MemberData(nameof(QuartzStoreFeatures))]
+ public void StoreMigrationInitializer_RunsInPreparePhase(IShellFeature feature)
+ {
+ var services = new ServiceCollection();
+
+ feature.ConfigureServices(services);
+
+ var initializer = Assert.Single(services, x => x.ServiceType == typeof(IShellInitializer));
+ var registrationDescriptor = Assert.Single(services, x => x.ServiceType == typeof(ShellInitializerRegistration));
+ var registration = Assert.IsType(registrationDescriptor.ImplementationInstance);
+
+ Assert.NotNull(initializer.ImplementationFactory);
+ Assert.Equal(LifecyclePhase.Prepare, registration.Phase);
+ Assert.Equal(100, registration.Order);
+ Assert.True(typeof(IShellInitializer).IsAssignableFrom(registration.InitializerType));
+ }
+
+ public static TheoryData QuartzStoreFeatures() => new()
+ {
+ new QuartzMySqlFeature(),
+ new QuartzPostgreSqlFeature(),
+ new QuartzSqlServerFeature(),
+ new QuartzSqliteFeature()
+ };
+
private sealed class DependentInitializer : IShellInitializer
{
public Task InitializeAsync(CancellationToken cancellationToken = default) => Task.CompletedTask;