< Summary

Information
Class: Elsa.Workflows.Runtime.Features.WorkflowRuntimeFeature
Assembly: Elsa.Workflows.Runtime
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs
Line coverage
94%
Covered lines: 243
Uncovered lines: 13
Coverable lines: 256
Total lines: 484
Line coverage: 94.9%
Branch coverage
100%
Covered branches: 14
Total branches: 14
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
get_WorkflowDispatcherChannels()100%11100%
get_Workflows()100%11100%
get_WorkflowTypes()100%11100%
get_WorkflowRuntime()100%11100%
get_WorkflowDispatcher()100%11100%
get_StimulusDispatcher()100%11100%
get_WorkflowCancellationDispatcher()100%11100%
get_WorkflowDispatchOutboxStore()100%11100%
get_BookmarkStore()100%11100%
get_BookmarkQueueStore()100%11100%
get_BookmarkQueueDeadLetterStore()100%11100%
get_TriggerStore()100%11100%
get_WorkflowExecutionLogStore()100%11100%
get_ActivityExecutionLogStore()100%11100%
get_DistributedLockProvider()100%11100%
get_RunTaskDispatcher()100%11100%
get_BackgroundActivityScheduler()100%11100%
get_ActivityExecutionLogSink()100%11100%
get_WorkflowExecutionLogSink()100%11100%
get_DispatchWorkflowCommandHandler()100%11100%
get_WorkflowResumer()100%11100%
get_BookmarkQueueWorker()100%11100%
get_DistributedLockingOptions()100%11100%
get_WorkflowInboxCleanupOptions()100%11100%
get_WorkflowDispatcherOptions()100%11100%
get_BookmarkQueuePurgeOptions()100%11100%
EnableWorkflowInboxCleanupJob()100%210%
DisableWorkflowInboxCleanupJob()100%210%
AddWorkflow()100%11100%
AddWorkflow(...)100%11100%
AddWorkflowsFrom(...)100%22100%
AddDispatcherChannel(...)100%210%
AddDispatcherChannel(...)100%210%
Configure()100%11100%
get_GracefulShutdown()100%11100%
Apply()100%11100%
RegisterWorkflowTypeAliases(...)100%11100%
GetRegisteredWorkflowTypes()100%11100%
TryResolveWorkflowType(...)100%201262.5%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs

#LineLine coverage
 1using System.Diagnostics.CodeAnalysis;
 2using System.Reflection;
 3using Elsa.Common;
 4using Elsa.Common.DistributedHosting;
 5using Elsa.Common.Features;
 6using Elsa.Common.RecurringTasks;
 7using Elsa.Extensions;
 8using Elsa.Features.Abstractions;
 9using Elsa.Features.Attributes;
 10using Elsa.Features.Services;
 11using Elsa.Mediator.Contracts;
 12using Elsa.Workflows.Features;
 13using Elsa.Workflows.Management;
 14using Elsa.Workflows.Management.Contracts;
 15using Elsa.Workflows.Management.Services;
 16using Elsa.Workflows.Options;
 17using Elsa.Workflows.Runtime.ActivationValidators;
 18using Elsa.Workflows.Runtime.Bookmarks;
 19using Elsa.Workflows.Runtime.Discovery;
 20using Elsa.Workflows.Runtime.Entities;
 21using Elsa.Workflows.Runtime.Handlers;
 22using Elsa.Workflows.Runtime.Models;
 23using Elsa.Workflows.Runtime.Options;
 24using Elsa.Workflows.Runtime.Providers;
 25using Elsa.Workflows.Runtime.Stimuli;
 26using Elsa.Workflows.Runtime.Stores;
 27using Elsa.Workflows.Runtime.Tasks;
 28using Elsa.Workflows.Runtime.UIHints;
 29using Medallion.Threading;
 30using Medallion.Threading.FileSystem;
 31using Microsoft.Extensions.DependencyInjection;
 32using Microsoft.Extensions.DependencyInjection.Extensions;
 33using Microsoft.Extensions.Options;
 34using Elsa.Common.Serialization;
 35
 36namespace Elsa.Workflows.Runtime.Features;
 37
 38/// <summary>
 39/// Installs and configures workflow runtime features.
 40/// </summary>
 41[DependsOn(typeof(SystemClockFeature))]
 42[DependsOn(typeof(WorkflowsFeature))]
 30243public class WorkflowRuntimeFeature(IModule module) : FeatureBase(module)
 44{
 51545    private IDictionary<string, DispatcherChannel> WorkflowDispatcherChannels { get; set; } = new Dictionary<string, Dis
 46
 47    /// <summary>
 48    /// A list of workflow builders configured during application startup.
 49    /// </summary>
 114950    public IDictionary<string, Func<IServiceProvider, ValueTask<IWorkflow>>> Workflows { get; set; } = new Dictionary<st
 91751    private ISet<Type> WorkflowTypes { get; } = new HashSet<Type>();
 52
 53    /// <summary>
 54    /// A factory that instantiates a concrete <see cref="IWorkflowRuntime"/>.
 55    /// </summary>
 105956    public Func<IServiceProvider, IWorkflowRuntime> WorkflowRuntime { get; set; } = sp => ActivatorUtilities.CreateInsta
 57
 58    /// <summary>
 59    /// A factory that instantiates an <see cref="IWorkflowDispatcher"/>.
 60    /// </summary>
 58661    public Func<IServiceProvider, IWorkflowDispatcher> WorkflowDispatcher { get; set; } = sp =>
 30262    {
 50863        var decoratedService = ActivatorUtilities.CreateInstance<BackgroundWorkflowDispatcher>(sp);
 50864        var transactionalService = ActivatorUtilities.CreateInstance<TransactionalWorkflowDispatcher>(sp, decoratedServi
 50865        return ActivatorUtilities.CreateInstance<ValidatingWorkflowDispatcher>(sp, transactionalService);
 30266    };
 67
 68    /// <summary>
 69    /// A factory that instantiates an <see cref="IStimulusDispatcher"/>.
 70    /// </summary>
 58671    public Func<IServiceProvider, IStimulusDispatcher> StimulusDispatcher { get; set; } = sp => ActivatorUtilities.Creat
 72
 73    /// <summary>
 74    /// A factory that instantiates an <see cref="IWorkflowCancellationDispatcher"/>.
 75    /// </summary>
 58976    public Func<IServiceProvider, IWorkflowCancellationDispatcher> WorkflowCancellationDispatcher { get; set; } = sp => 
 77
 78    /// <summary>
 79    /// A factory that instantiates an <see cref="IWorkflowDispatchOutboxStore"/>.
 80    /// </summary>
 58881    public Func<IServiceProvider, IWorkflowDispatchOutboxStore> WorkflowDispatchOutboxStore { get; set; } = sp => Activa
 82
 83    /// <summary>
 84    /// A factory that instantiates an <see cref="IBookmarkStore"/>.
 85    /// </summary>
 106886    public Func<IServiceProvider, IBookmarkStore> BookmarkStore { get; set; } = sp => sp.GetRequiredService<MemoryBookma
 87
 88    /// <summary>
 89    /// A factory that instantiates an <see cref="IBookmarkQueueStore"/>.
 90    /// </summary>
 106791    public Func<IServiceProvider, IBookmarkQueueStore> BookmarkQueueStore { get; set; } = sp => sp.GetRequiredService<Me
 92
 93    /// <summary>
 94    /// A factory that instantiates an <see cref="IBookmarkQueueDeadLetterStore"/>.
 95    /// </summary>
 82096    public Func<IServiceProvider, IBookmarkQueueDeadLetterStore> BookmarkQueueDeadLetterStore { get; set; } = sp => sp.G
 97
 98    /// <summary>
 99    /// A factory that instantiates an <see cref="ITriggerStore"/>.
 100    /// </summary>
 921101    public Func<IServiceProvider, ITriggerStore> TriggerStore { get; set; } = sp => sp.GetRequiredService<MemoryTriggerS
 102
 103    /// <summary>
 104    /// A factory that instantiates an <see cref="IWorkflowExecutionLogStore"/>.
 105    /// </summary>
 926106    public Func<IServiceProvider, IWorkflowExecutionLogStore> WorkflowExecutionLogStore { get; set; } = sp => sp.GetRequ
 107
 108    /// <summary>
 109    /// A factory that instantiates an <see cref="IActivityExecutionStore"/>.
 110    /// </summary>
 911111    public Func<IServiceProvider, IActivityExecutionStore> ActivityExecutionLogStore { get; set; } = sp => sp.GetRequire
 112
 113    /// <summary>
 114    /// A factory that instantiates an <see cref="IDistributedLockProvider"/>.
 115    /// </summary>
 815116    public Func<IServiceProvider, IDistributedLockProvider> DistributedLockProvider { get; set; } = _ => new FileDistrib
 117
 118    /// <summary>
 119    /// A factory that instantiates an <see cref="ITaskDispatcher"/>.
 120    /// </summary>
 586121    public Func<IServiceProvider, ITaskDispatcher> RunTaskDispatcher { get; set; } = sp => sp.GetRequiredService<Backgro
 122
 123    /// <summary>
 124    /// A factory that instantiates an <see cref="IBackgroundActivityScheduler"/>.
 125    /// </summary>
 815126    public Func<IServiceProvider, IBackgroundActivityScheduler> BackgroundActivityScheduler { get; set; } = sp => Activa
 127
 128    /// <summary>
 129    /// A factory that instantiates a log record sink for an <see cref="ActivityExecutionRecord"/>.
 130    /// </summary>
 1153131    public Func<IServiceProvider, ILogRecordSink<ActivityExecutionRecord>> ActivityExecutionLogSink { get; set; } = sp =
 132
 133    /// <summary>
 134    /// A factory that instantiates a log record sink for an <see cref="WorkflowExecutionLogRecord"/>.
 135    /// </summary>
 1153136    public Func<IServiceProvider, ILogRecordSink<WorkflowExecutionLogRecord>> WorkflowExecutionLogSink { get; set; } = s
 137
 138    /// <summary>
 139    /// A factory that instantiates an <see cref="ICommandHandler"/>.
 140    /// </summary>
 302141    public Func<IServiceProvider, ICommandHandler> DispatchWorkflowCommandHandler { get; set; } = sp => sp.GetRequiredSe
 142
 143    /// <summary>
 144    /// A factory that instantiates an <see cref="IWorkflowResumer"/>.
 145    /// </summary>
 1678146    public Func<IServiceProvider, IWorkflowResumer> WorkflowResumer { get; set; } = sp => sp.GetRequiredService<Workflow
 147
 148    /// <summary>
 149    /// A factory that instantiates an <see cref="IBookmarkQueueWorker"/>.
 150    /// </summary>
 959151    public Func<IServiceProvider, IBookmarkQueueWorker> BookmarkQueueWorker { get; set; } = sp => sp.GetRequiredService<
 152
 153    /// <summary>
 154    /// A delegate to configure the <see cref="DistributedLockingOptions"/>.
 155    /// </summary>
 818156    public Action<DistributedLockingOptions> DistributedLockingOptions { get; set; } = _ => { };
 157
 158    /// <summary>
 159    /// A delegate to configure the <see cref="WorkflowInboxCleanupOptions"/>.
 160    /// </summary>
 161    [Obsolete("Will be removed in a future version")]
 586162    public Action<WorkflowInboxCleanupOptions> WorkflowInboxCleanupOptions { get; set; } = _ => { };
 163
 164    /// <summary>
 165    /// A delegate to configure the <see cref="WorkflowDispatcherOptions"/>.
 166    /// </summary>
 799167    public Action<WorkflowDispatcherOptions> WorkflowDispatcherOptions { get; set; } = _ => { };
 168
 169    /// <summary>
 170    /// A delegate to configure the <see cref="BookmarkQueuePurgeOptions"/>.
 171    /// </summary>
 641172    public Action<BookmarkQueuePurgeOptions> BookmarkQueuePurgeOptions { get; set; } = _ => { };
 173
 174    /// <summary>
 175    /// Enables the workflow inbox cleanup job.
 176    /// </summary>
 177    public WorkflowRuntimeFeature EnableWorkflowInboxCleanupJob()
 178    {
 0179        Services.Configure<WorkflowInboxCleanupOptions>(options => { options.IsEnabled = true; });
 0180        return this;
 181    }
 182
 183    /// <summary>
 184    /// Disables the workflow inbox cleanup job.
 185    /// </summary>
 186    public WorkflowRuntimeFeature DisableWorkflowInboxCleanupJob()
 187    {
 0188        Services.Configure<WorkflowInboxCleanupOptions>(options => { options.IsEnabled = false; });
 0189        return this;
 190    }
 191
 192    /// <summary>
 193    /// Register the specified workflow type.
 194    /// </summary>
 195    public WorkflowRuntimeFeature AddWorkflow<T>() where T : IWorkflow
 196    {
 162197        AddWorkflow(typeof(T));
 162198        return this;
 199    }
 200
 201    /// <summary>
 202    /// Register the specified workflow type.
 203    /// </summary>
 204    public WorkflowRuntimeFeature AddWorkflow(Type workflowType)
 205    {
 360206        Workflows.Add(workflowType);
 356207        WorkflowTypes.Add(workflowType);
 356208        return this;
 209    }
 210
 211    /// <summary>
 212    /// Register all workflows in the specified assembly.
 213    /// </summary>
 214    [RequiresUnreferencedCode("The assembly is required to be referenced.")]
 215    public WorkflowRuntimeFeature AddWorkflowsFrom(Assembly assembly)
 216    {
 396217        foreach (var workflowType in WorkflowTypeScanner.GetWorkflowTypes(assembly))
 192218            AddWorkflow(workflowType);
 219
 6220        return this;
 221    }
 222
 223    /// <summary>
 224    /// Adds a dispatcher channel.
 225    /// </summary>
 226    public WorkflowRuntimeFeature AddDispatcherChannel(string channel)
 227    {
 0228        return AddDispatcherChannel(new DispatcherChannel
 0229        {
 0230            Name = channel
 0231        });
 232    }
 233
 234    /// <summary>
 235    /// Adds a dispatcher channel.
 236    /// </summary>
 237    public WorkflowRuntimeFeature AddDispatcherChannel(DispatcherChannel channel)
 238    {
 0239        WorkflowDispatcherChannels[channel.Name] = channel;
 0240        return this;
 241    }
 242
 243    /// <inheritdoc />
 244    public override void Configure()
 245    {
 284246        Module.AddActivitiesFrom<WorkflowRuntimeFeature>();
 284247        Module.Configure<WorkflowsFeature>(workflows =>
 284248        {
 284249            // ExecutionCycleAwareCommitStateHandler decorates DefaultCommitStateHandler â€” disposes the execution cycle 
 284250            // commit so the drain orchestrator's await-disposed sequencing can land its Interrupted write last.
 851251            workflows.CommitStateHandler = sp => sp.GetRequiredService<Elsa.Workflows.Runtime.Services.ExecutionCycleAwa
 568252        });
 253
 284254        Services.Configure<RecurringTaskOptions>(options =>
 284255        {
 86256            options.Schedule.ConfigureTask<TriggerBookmarkQueueRecurringTask>(TimeSpan.FromSeconds(10));
 370257        });
 284258    }
 259
 260    /// <inheritdoc />
 261    /// <summary>
 262    /// Callback that tunes the graceful-shutdown machinery (drain deadline, per-source pause timeout, stimulus-queue ba
 263    /// pause-persistence policy). Applied when <see cref="Apply"/> binds <see cref="GracefulShutdownOptions"/>.
 264    /// </summary>
 291265    public Action<GracefulShutdownOptions>? GracefulShutdown { get; set; }
 266
 267    public override void Apply()
 268    {
 269        // Options.
 284270        Services.Configure(DistributedLockingOptions);
 284271        Services.Configure(WorkflowInboxCleanupOptions);
 284272        Services.Configure(WorkflowDispatcherOptions);
 284273        Services.Configure(BookmarkQueuePurgeOptions);
 284274        Services.Configure<SerializationTypeOptions>(RegisterWorkflowTypeAliases);
 714275        Services.Configure<RuntimeOptions>(options => { options.Workflows = Workflows; });
 284276        Services.Configure<WorkflowDispatcherOptions>(options =>
 284277        {
 213278            options.Channels.AddRange(WorkflowDispatcherChannels.Values);
 497279        });
 284280        Services.TryAddSingleton(TimeProvider.System);
 284281        Services.AddGracefulShutdownOptions(GracefulShutdown);
 282
 283        // Graceful-shutdown core (US1 â€” quiescence machinery).
 284284        Services
 106285            .AddSingleton<IQuiescenceSignal>(sp => new Elsa.Workflows.Runtime.Services.QuiescenceSignal(
 106286                sp.GetRequiredService<IOptions<GracefulShutdownOptions>>(),
 106287                sp.GetRequiredService<ISystemClock>(),
 106288                sp.GetRequiredService<IExecutionCycleRegistry>(),
 106289                sp.GetRequiredService<IServiceScopeFactory>()))
 284290            .AddSingleton<IIngressSourceRegistry, Elsa.Workflows.Runtime.Services.IngressSourceRegistry>()
 284291            .AddSingleton<IExecutionCycleRegistry, Elsa.Workflows.Runtime.Services.ExecutionCycleRegistry>()
 284292            // Lazy collection breaks the otherwise-circular DI chain QuiescenceSignal â†’ IExecutionCycleRegistry â†’
 284293            // IIngressSourceRegistry â†’ IEnumerable<IIngressSource> â†’ IQuiescenceSignal. Adapters take a direct
 284294            // IQuiescenceSignal dependency; the registry materializes the collection on first read.
 199295            .AddSingleton(sp => new Lazy<IEnumerable<IIngressSource>>(sp.GetServices<IIngressSource>))
 284296            // Drain orchestrator + hosted service (US1). See FR-029 / R5 â€” heartbeat must outlive drain.
 284297            .AddSingleton<IDrainOrchestrator, Elsa.Workflows.Runtime.Services.DrainOrchestrator>()
 284298            .AddHostedService<Elsa.Workflows.Runtime.HostedServices.DrainOrchestratorHostedService>()
 284299            // Domain service that backs all runtime-admin transports (US2). Encapsulates the audit-on-effective-
 284300            // transition rule (SC-007) so transports stay thin. Scoped because INotificationSender is scoped.
 284301            .AddScoped<IWorkflowRuntimeAdminService, Elsa.Workflows.Runtime.Services.WorkflowRuntimeAdminService>()
 284302            // Interrupted-workflow recovery on shell activation (US3). Disjoint from the timeout-based
 284303            // RestartInterruptedWorkflowsTask: filter is SubStatus = Interrupted AND Status = Running;
 284304            // that task's filter is IsExecuting=true.
 284305            .AddScoped<IInterruptedRecoveryScanner, Elsa.Workflows.Runtime.Services.InterruptedRecoveryScanner>()
 284306            .AddStartupTask<Elsa.Workflows.Runtime.StartupTasks.RecoverInterruptedWorkflowsStartupTask>()
 284307            // Internal bookmark-queue processor surfaced as an ingress source for diagnostic visibility (FR-006).
 284308            // Pause behavior is enforced inside BookmarkQueueProcessor via IQuiescenceSignal (FR-024).
 284309            .AddSingleton<IIngressSource, Elsa.Workflows.Runtime.IngressSources.InternalBookmarkQueueIngressSource>()
 284310            // Re-applies persisted pause state on activation when PausePersistence = AcrossReactivations (FR-028).
 284311            .AddStartupTask<Elsa.Workflows.Runtime.StartupTasks.InitializePauseStateStartupTask>();
 312
 284313        Services
 284314            // Core.
 284315            .AddScoped<ITriggerIndexer, TriggerIndexer>()
 284316            .AddScoped<IWorkflowInstanceFactory, WorkflowInstanceFactory>()
 284317            .AddScoped<IWorkflowHostFactory, WorkflowHostFactory>()
 284318            .AddScoped<IBackgroundActivityInvoker, BackgroundActivityInvoker>()
 284319            .AddScoped(WorkflowRuntime)
 284320            .AddScoped(WorkflowDispatcher)
 284321            .AddScoped(StimulusDispatcher)
 284322            .AddScoped(WorkflowCancellationDispatcher)
 284323            .AddScoped(RunTaskDispatcher)
 284324            .AddScoped(ActivityExecutionLogSink)
 284325            .AddScoped(WorkflowExecutionLogSink)
 284326            .AddSingleton(BackgroundActivityScheduler)
 284327            .AddSingleton<RandomLongIdentityGenerator>()
 284328            .AddSingleton<IBookmarkQueueSignaler, BookmarkQueueSignaler>()
 284329            .AddScoped(BookmarkQueueWorker)
 284330            .AddScoped<IBookmarkManager, DefaultBookmarkManager>()
 284331            .AddScoped<IActivityExecutionManager, DefaultActivityExecutionManager>()
 284332            .AddScoped<IActivityExecutionStatsService, ActivityExecutionStatsService>()
 284333            .AddScoped<IActivityExecutionMapper, DefaultActivityExecutionMapper>()
 284334            .AddScoped<IWorkflowDefinitionStorePopulator, DefaultWorkflowDefinitionStorePopulator>()
 284335            .AddScoped<IRegistriesPopulator, DefaultRegistriesPopulator>()
 284336            .AddScoped<IWorkflowDefinitionsRefresher, WorkflowDefinitionsRefresher>()
 284337            .AddScoped<IWorkflowDefinitionsReloader, WorkflowDefinitionsReloader>()
 284338            .AddScoped<IWorkflowRegistry, DefaultWorkflowRegistry>()
 284339            .AddScoped<IWorkflowMatcher, WorkflowMatcher>()
 284340            .AddScoped<IWorkflowInvoker, WorkflowInvoker>()
 284341            .AddScoped<IStimulusSender, StimulusSender>()
 284342            .AddScoped<ITriggerBoundWorkflowService, TriggerBoundWorkflowService>()
 284343            .AddScoped<IBookmarkBoundWorkflowService, BookmarkBoundWorkflowService>()
 284344            .AddScoped<ITaskReporter, TaskReporter>()
 284345            .AddScoped<SynchronousTaskDispatcher>()
 284346            .AddScoped<BackgroundTaskDispatcher>()
 284347            .AddScoped<StoreActivityExecutionLogSink>()
 284348            .AddScoped<StoreWorkflowExecutionLogSink>()
 284349            .AddScoped<DispatchWorkflowCommandHandler>()
 284350            .AddScoped<IEventPublisher, EventPublisher>()
 284351            .AddScoped<IBookmarkUpdater, BookmarkUpdater>()
 284352            .AddScoped<IBookmarksPersister, BookmarksPersister>()
 284353            .AddScoped<IBookmarkResumer, BookmarkResumer>()
 284354            .AddScoped<IBookmarkQueue, StoreBookmarkQueue>()
 284355            .AddScoped<IBookmarkQueueDeadLetterManager, BookmarkQueueDeadLetterManager>()
 284356            .AddScoped(WorkflowResumer)
 284357            .AddScoped<WorkflowResumer>()
 284358            .AddScoped(BookmarkQueueWorker)
 284359            .AddScoped<BookmarkQueueWorker>()
 284360            .AddScoped<ITriggerInvoker, TriggerInvoker>()
 284361            .AddScoped<IWorkflowCanceler, WorkflowCanceler>()
 284362            .AddScoped<IWorkflowCancellationService, WorkflowCancellationService>()
 284363            .AddScoped<IWorkflowActivationStrategyEvaluator, DefaultWorkflowActivationStrategyEvaluator>()
 284364            .AddScoped<IWorkflowActivationGate, WorkflowActivationGate>()
 284365            .AddScoped<IWorkflowStarter, DefaultWorkflowStarter>()
 284366            .AddScoped<IWorkflowRestarter, DefaultWorkflowRestarter>()
 284367            .AddScoped<IBookmarkQueuePurger, DefaultBookmarkQueuePurger>()
 284368            .AddSingleton<IWorkflowDispatchOutboxAccessor, WorkflowDispatchOutboxAccessor>()
 284369            .AddScoped<ILogRecordExtractor<WorkflowExecutionLogRecord>, WorkflowExecutionLogRecordExtractor>()
 284370            .AddScoped<IActivityPropertyLogPersistenceEvaluator, ActivityPropertyLogPersistenceEvaluator>()
 284371            .AddScoped<IBookmarkQueueProcessor, BookmarkQueueProcessor>()
 284372            .AddScoped<WorkflowCommitNotificationBuffer>()
 567373            .AddScoped<IWorkflowCommitNotificationBuffer>(sp => sp.GetRequiredService<WorkflowCommitNotificationBuffer>(
 284374            .AddScoped<INotificationSender, WorkflowCommitNotificationSender>()
 284375            .AddScoped<IWorkflowCommitTransaction, NoopWorkflowCommitTransaction>()
 284376            .AddScoped<DefaultCommitStateHandler>()
 284377            .AddScoped<Elsa.Workflows.Runtime.Services.ExecutionCycleAwareCommitStateHandler>()
 284378            .AddScoped<WorkflowHeartbeatGeneratorFactory>()
 284379
 284380            // Deprecated services.
 284381            .AddScoped<IWorkflowInbox, StimulusProxyWorkflowInbox>()
 284382
 284383            // Stores.
 284384            .AddScoped(BookmarkStore)
 284385            .AddScoped(BookmarkQueueStore)
 284386            .AddScoped(BookmarkQueueDeadLetterStore)
 284387            .AddScoped(TriggerStore)
 284388            .AddScoped(WorkflowExecutionLogStore)
 284389            .AddScoped(ActivityExecutionLogStore)
 284390
 284391            // Lazy services.
 219392            .AddScoped<Func<IEnumerable<IWorkflowsProvider>>>(sp => sp.GetServices<IWorkflowsProvider>)
 763393            .AddScoped<Func<IEnumerable<IWorkflowMaterializer>>>(sp => sp.GetServices<IWorkflowMaterializer>)
 284394
 284395            // Noop stores.
 284396            .AddScoped<MemoryWorkflowExecutionLogStore>()
 284397            .AddScoped<MemoryActivityExecutionStore>()
 284398
 284399            // Memory stores.
 284400            .AddMemoryStore<StoredBookmark, MemoryBookmarkStore>()
 284401            .AddMemoryStore<StoredTrigger, MemoryTriggerStore>()
 284402            .AddMemoryStore<BookmarkQueueItem, MemoryBookmarkQueueStore>()
 284403            .AddMemoryStore<BookmarkQueueDeadLetterItem, MemoryBookmarkQueueDeadLetterStore>()
 284404            .AddMemoryStore<WorkflowExecutionLogRecord, MemoryWorkflowExecutionLogStore>()
 284405            .AddMemoryStore<ActivityExecutionRecord, MemoryActivityExecutionStore>()
 284406
 284407            // Startup tasks, background tasks, and recurring tasks.
 284408            .AddStartupTask<PopulateRegistriesStartupTask>()
 284409            .AddRecurringTask<TriggerBookmarkQueueRecurringTask>(TimeSpan.FromMinutes(1))
 284410            .AddRecurringTask<PurgeBookmarkQueueRecurringTask>(TimeSpan.FromSeconds(10))
 284411            .AddRecurringTask<RestartInterruptedWorkflowsTask>(TimeSpan.FromMinutes(5)) // Same default as the workflow 
 284412            .AddRecurringTask<ProcessWorkflowDispatchOutboxRecurringTask>(TimeSpan.FromSeconds(10))
 284413            .AddRecurringTask<RefreshWorkflowDefinitionActivityRegistryTask>(TimeSpan.FromSeconds(5))
 284414
 284415            // Distributed locking.
 284416            .AddSingleton(DistributedLockProvider)
 284417
 284418            // Workflow providers.
 284419            .AddWorkflowsProvider<ClrWorkflowsProvider>()
 284420
 284421            // UI property handlers.
 284422            .AddScoped<IPropertyUIHandler, DispatcherChannelOptionsProvider>()
 284423
 284424            // Domain handlers.
 284425            .AddCommandHandler<DispatchWorkflowCommandHandler>()
 284426            .AddCommandHandler<DispatchStimulusCommandHandler>()
 284427            .AddCommandHandler<CancelWorkflowsCommandHandler>()
 284428            .AddNotificationHandler<ResumeDispatchWorkflowActivity>()
 284429            .AddNotificationHandler<ResumeBulkDispatchWorkflowActivity>()
 284430            .AddNotificationHandler<ProcessWorkflowDispatchOutbox>()
 284431            .AddNotificationHandler<ResumeExecuteWorkflowActivity>()
 284432            .AddNotificationHandler<IndexTriggers>()
 284433            .AddNotificationHandler<CancelBackgroundActivities>()
 284434            .AddNotificationHandler<DeleteBookmarks>()
 284435            .AddNotificationHandler<DeleteTriggers>()
 284436            .AddNotificationHandler<DeleteActivityExecutionLogRecords>()
 284437            .AddNotificationHandler<DeleteWorkflowExecutionLogRecords>()
 284438            .AddNotificationHandler<RefreshActivityRegistry>()
 284439            .AddNotificationHandler<SignalBookmarkQueueWorker>()
 284440            .AddNotificationHandler<EvaluateParentLogPersistenceModes>()
 284441            .AddNotificationHandler<CaptureActivityExecutionState>()
 284442            .AddNotificationHandler<ValidateWorkflowRequestHandler>()
 284443
 284444            // Workflow activation strategies.
 284445            .AddScoped<IWorkflowActivationStrategy, SingletonStrategy>()
 284446            .AddScoped<IWorkflowActivationStrategy, CorrelatedSingletonStrategy>()
 284447            .AddScoped<IWorkflowActivationStrategy, CorrelationStrategy>()
 284448            ;
 449
 285450        Services.TryAddScoped<IWorkflowDispatchOutbox>(sp => ActivatorUtilities.CreateInstance<WorkflowDispatchOutbox>(s
 284451        Services.TryAddScoped(WorkflowDispatchOutboxStore);
 284452        Services.TryAddScoped<IWorkflowDispatchOutboxProcessor, WorkflowDispatchOutboxProcessor>();
 284453    }
 454
 455    private void RegisterWorkflowTypeAliases(SerializationTypeOptions options)
 456    {
 259457        WorkflowRuntimeTypeAliasRegistrar.Register(options, GetRegisteredWorkflowTypes());
 259458    }
 459
 460    private IEnumerable<Type> GetRegisteredWorkflowTypes()
 461    {
 259462        return WorkflowTypes
 1063463            .Concat(Workflows.Keys.Select(TryResolveWorkflowType).Where(type => type != null).Select(type => type!))
 259464            .Distinct();
 465    }
 466
 467    private static Type? TryResolveWorkflowType(string typeName)
 468    {
 469        Type? type;
 470
 471        try
 472        {
 709473            type = Type.GetType(typeName, false);
 709474        }
 0475        catch (Exception e) when (e is ArgumentException or FileLoadException or FileNotFoundException or TypeLoadExcept
 476        {
 0477            return null;
 478        }
 479
 709480        return type != null && typeof(IWorkflow).IsAssignableFrom(type) && type is { IsAbstract: false, IsInterface: fal
 709481            ? type
 709482            : null;
 0483    }
 484}