< Summary

Information
Class: Elsa.Workflows.Runtime.ShellFeatures.WorkflowRuntimeFeature
Assembly: Elsa.Workflows.Runtime
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Runtime/ShellFeatures/WorkflowRuntimeFeature.cs
Line coverage
16%
Covered lines: 37
Uncovered lines: 189
Coverable lines: 226
Total lines: 401
Line coverage: 16.3%
Branch coverage
66%
Covered branches: 12
Total branches: 18
Branch coverage: 66.6%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

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

#LineLine coverage
 1using System.Diagnostics.CodeAnalysis;
 2using System.Reflection;
 3using CShells.Features;
 4using Elsa.Common.RecurringTasks;
 5using Elsa.Common.Serialization;
 6using Elsa.Common;
 7using Elsa.Extensions;
 8using Elsa.Mediator.Contracts;
 9using Elsa.Workflows.CommitStates;
 10using Elsa.Workflows.Management.Contracts;
 11using Elsa.Workflows.Management.Services;
 12using Elsa.Workflows.Management;
 13using Elsa.Workflows.Options;
 14using Elsa.Workflows.Runtime.ActivationValidators;
 15using Elsa.Workflows.Runtime.Discovery;
 16using Elsa.Workflows.Runtime.Entities;
 17using Elsa.Workflows.Runtime.Handlers;
 18using Elsa.Workflows.Runtime.Options;
 19using Elsa.Workflows.Runtime.Providers;
 20using Elsa.Workflows.Runtime.Services;
 21using Elsa.Workflows.Runtime.Stores;
 22using Elsa.Workflows.Runtime.Tasks;
 23using Elsa.Workflows.Runtime.UIHints;
 24using Elsa.Workflows.ShellFeatures;
 25using Elsa.Platform.PackageManifest.Generator.Hints;
 26using Medallion.Threading.FileSystem;
 27using Medallion.Threading;
 28using Microsoft.Extensions.DependencyInjection.Extensions;
 29using Microsoft.Extensions.DependencyInjection;
 30using Microsoft.Extensions.Options;
 31
 32namespace Elsa.Workflows.Runtime.ShellFeatures;
 33
 34/// <summary>
 35/// Installs and configures workflow runtime features.
 36/// </summary>
 37[ManifestFeatureCategory("Workflows")]
 38[ShellFeature(
 39    DisplayName = "Workflow Runtime",
 40    Description = "Provides workflow execution runtime and scheduling capabilities",
 41    DependsOn = [typeof(WorkflowsFeature)])]
 42public class WorkflowRuntimeFeature : IShellFeature
 43{
 1844    private IDictionary<string, DispatcherChannel> WorkflowDispatcherChannels { get; set; } = new Dictionary<string, Dis
 45
 46    /// <summary>
 47    /// A list of workflow builders configured during application startup.
 48    /// </summary>
 3049    public IDictionary<string, Func<IServiceProvider, ValueTask<IWorkflow>>> Workflows { get; set; } = new Dictionary<st
 2250    private ISet<Type> WorkflowTypes { get; } = new HashSet<Type>();
 51
 52    /// <summary>
 53    /// A factory that instantiates a concrete <see cref="IWorkflowRuntime"/>.
 54    /// </summary>
 1855    public Func<IServiceProvider, IWorkflowRuntime> WorkflowRuntime { get; set; } = sp => ActivatorUtilities.CreateInsta
 56
 57    /// <summary>
 58    /// A factory that instantiates an <see cref="IWorkflowDispatcher"/>.
 59    /// </summary>
 1860    public Func<IServiceProvider, IWorkflowDispatcher> WorkflowDispatcher { get; set; } = sp =>
 1861    {
 062        var decoratedService = ActivatorUtilities.CreateInstance<BackgroundWorkflowDispatcher>(sp);
 063        var transactionalService = ActivatorUtilities.CreateInstance<TransactionalWorkflowDispatcher>(sp, decoratedServi
 064        return ActivatorUtilities.CreateInstance<ValidatingWorkflowDispatcher>(sp, transactionalService);
 1865    };
 66
 67    /// <summary>
 68    /// A factory that instantiates an <see cref="IStimulusDispatcher"/>.
 69    /// </summary>
 1870    public Func<IServiceProvider, IStimulusDispatcher> StimulusDispatcher { get; set; } = sp => ActivatorUtilities.Creat
 71
 72    /// <summary>
 73    /// A factory that instantiates an <see cref="IWorkflowCancellationDispatcher"/>.
 74    /// </summary>
 1875    public Func<IServiceProvider, IWorkflowCancellationDispatcher> WorkflowCancellationDispatcher { get; set; } = sp => 
 76
 77    /// <summary>
 78    /// A factory that instantiates an <see cref="IWorkflowDispatchOutboxStore"/>.
 79    /// </summary>
 1880    public Func<IServiceProvider, IWorkflowDispatchOutboxStore> WorkflowDispatchOutboxStore { get; set; } = sp => Activa
 81
 82    /// <summary>
 83    /// A factory that instantiates an <see cref="IBookmarkStore"/>.
 84    /// </summary>
 1885    public Func<IServiceProvider, IBookmarkStore> BookmarkStore { get; set; } = sp => sp.GetRequiredService<MemoryBookma
 86
 87    /// <summary>
 88    /// A factory that instantiates an <see cref="IBookmarkQueueStore"/>.
 89    /// </summary>
 1890    public Func<IServiceProvider, IBookmarkQueueStore> BookmarkQueueStore { get; set; } = sp => sp.GetRequiredService<Me
 91
 92    /// <summary>
 93    /// A factory that instantiates an <see cref="IBookmarkQueueDeadLetterStore"/>.
 94    /// </summary>
 1895    public Func<IServiceProvider, IBookmarkQueueDeadLetterStore> BookmarkQueueDeadLetterStore { get; set; } = sp => sp.G
 96
 97    /// <summary>
 98    /// A factory that instantiates an <see cref="ITriggerStore"/>.
 99    /// </summary>
 18100    public Func<IServiceProvider, ITriggerStore> TriggerStore { get; set; } = sp => sp.GetRequiredService<MemoryTriggerS
 101
 102    /// <summary>
 103    /// A factory that instantiates an <see cref="IWorkflowExecutionLogStore"/>.
 104    /// </summary>
 18105    public Func<IServiceProvider, IWorkflowExecutionLogStore> WorkflowExecutionLogStore { get; set; } = sp => sp.GetRequ
 106
 107    /// <summary>
 108    /// A factory that instantiates an <see cref="IActivityExecutionStore"/>.
 109    /// </summary>
 18110    public Func<IServiceProvider, IActivityExecutionStore> ActivityExecutionLogStore { get; set; } = sp => sp.GetRequire
 111
 112    /// <summary>
 113    /// A factory that instantiates an <see cref="IDistributedLockProvider"/>.
 114    /// </summary>
 18115    public Func<IServiceProvider, IDistributedLockProvider> DistributedLockProvider { get; set; } = _ => new FileDistrib
 116
 117    /// <summary>
 118    /// A factory that instantiates an <see cref="ITaskDispatcher"/>.
 119    /// </summary>
 18120    public Func<IServiceProvider, ITaskDispatcher> RunTaskDispatcher { get; set; } = sp => sp.GetRequiredService<Backgro
 121
 122    /// <summary>
 123    /// A factory that instantiates an <see cref="IBackgroundActivityScheduler"/>.
 124    /// </summary>
 18125    public Func<IServiceProvider, IBackgroundActivityScheduler> BackgroundActivityScheduler { get; set; } = sp => Activa
 126
 127    /// <summary>
 128    /// A factory that instantiates a log record sink for an <see cref="ActivityExecutionRecord"/>.
 129    /// </summary>
 18130    public Func<IServiceProvider, ILogRecordSink<ActivityExecutionRecord>> ActivityExecutionLogSink { get; set; } = sp =
 131
 132    /// <summary>
 133    /// A factory that instantiates a log record sink for an <see cref="WorkflowExecutionLogRecord"/>.
 134    /// </summary>
 18135    public Func<IServiceProvider, ILogRecordSink<WorkflowExecutionLogRecord>> WorkflowExecutionLogSink { get; set; } = s
 136
 137    /// <summary>
 138    /// A factory that instantiates an <see cref="ICommandHandler"/>.
 139    /// </summary>
 18140    public Func<IServiceProvider, ICommandHandler> DispatchWorkflowCommandHandler { get; set; } = sp => sp.GetRequiredSe
 141
 142    /// <summary>
 143    /// A factory that instantiates an <see cref="IWorkflowResumer"/>.
 144    /// </summary>
 18145    public Func<IServiceProvider, IWorkflowResumer> WorkflowResumer { get; set; } = sp => sp.GetRequiredService<Workflow
 146
 147    /// <summary>
 148    /// A factory that instantiates an <see cref="IBookmarkQueueWorker"/>.
 149    /// </summary>
 18150    public Func<IServiceProvider, IBookmarkQueueWorker> BookmarkQueueWorker { get; set; } = sp => sp.GetRequiredService<
 151
 152    /// <summary>
 153    /// Callback that tunes the graceful-shutdown machinery (drain deadline, per-source pause timeout, stimulus-queue ba
 154    /// pause-persistence policy). Applied when <see cref="ConfigureServices"/> binds <see cref="GracefulShutdownOptions
 155    /// </summary>
 0156    public GracefulShutdownOptions? GracefulShutdown { get; set; }
 157
 158    /// <summary>
 159    /// Register the specified workflow type.
 160    /// </summary>
 161    public WorkflowRuntimeFeature AddWorkflow<T>() where T : IWorkflow
 162    {
 0163        return AddWorkflow(typeof(T));
 164    }
 165
 166    /// <summary>
 167    /// Register the specified workflow type.
 168    /// </summary>
 169    public WorkflowRuntimeFeature AddWorkflow(Type workflowType)
 170    {
 6171        Workflows.Add(workflowType);
 2172        WorkflowTypes.Add(workflowType);
 2173        return this;
 174    }
 175
 176    /// <summary>
 177    /// Register all workflows in the specified assembly.
 178    /// </summary>
 179    [RequiresUnreferencedCode("The assembly is required to be referenced.")]
 180    public WorkflowRuntimeFeature AddWorkflowsFrom(Assembly assembly)
 181    {
 0182        foreach (var workflowType in WorkflowTypeScanner.GetWorkflowTypes(assembly))
 0183            AddWorkflow(workflowType);
 184
 0185        return this;
 186    }
 187
 188    public void ConfigureServices(IServiceCollection services)
 189    {
 190        // Options.
 0191        services.Configure<SerializationTypeOptions>(RegisterWorkflowTypeAliases);
 0192        services.Configure<RuntimeOptions>(options => { options.Workflows = Workflows; });
 0193        services.Configure<WorkflowDispatcherOptions>(options =>
 0194        {
 0195            options.Channels.AddRange(WorkflowDispatcherChannels.Values);
 0196        });
 0197        services.AddGracefulShutdownOptions(options =>
 0198        {
 0199            if (GracefulShutdown == null)
 0200                return;
 0201
 0202            options.DrainDeadline = GracefulShutdown.DrainDeadline;
 0203            options.IngressPauseTimeout = GracefulShutdown.IngressPauseTimeout;
 0204            options.StimulusQueueMaxDepthWhilePaused = GracefulShutdown.StimulusQueueMaxDepthWhilePaused;
 0205            options.OverflowPolicy = GracefulShutdown.OverflowPolicy;
 0206            options.PausePersistence = GracefulShutdown.PausePersistence;
 0207            options.MaxForceCancelledInstanceIdsReported = GracefulShutdown.MaxForceCancelledInstanceIdsReported;
 0208        });
 209
 0210        services
 0211            // Graceful-shutdown core (US1 â€” quiescence machinery).
 0212            // Per-shell QuiescenceSignal: the persistence key includes the shell id so multi-shell deployments under
 0213            // PausePersistencePolicy.AcrossReactivations don't collide on a single key. Falls back to "default" only
 0214            // when ShellSettings isn't in the DI graph (degenerate single-shell or non-CShells host).
 0215            .AddSingleton<IQuiescenceSignal>(sp => new QuiescenceSignal(
 0216                sp.GetRequiredService<IOptions<GracefulShutdownOptions>>(),
 0217                sp.GetRequiredService<ISystemClock>(),
 0218                sp.GetRequiredService<IExecutionCycleRegistry>(),
 0219                sp.GetRequiredService<IServiceScopeFactory>(),
 0220                shellName: sp.GetService<CShells.ShellSettings>()?.Id))
 0221            .AddSingleton<IIngressSourceRegistry, IngressSourceRegistry>()
 0222            .AddSingleton<IExecutionCycleRegistry, ExecutionCycleRegistry>()
 0223            .AddSingleton(sp => new Lazy<IEnumerable<IIngressSource>>(sp.GetServices<IIngressSource>))
 0224            .AddSingleton<IDrainOrchestrator, DrainOrchestrator>()
 0225            .AddScoped<IWorkflowRuntimeAdminService, WorkflowRuntimeAdminService>()
 0226            .AddTransient<CShells.Lifecycle.IDrainHandler, Lifecycle.ElsaShellDrainHandler>()
 0227            .AddScoped<IInterruptedRecoveryScanner, InterruptedRecoveryScanner>()
 0228            .AddStartupTask<StartupTasks.RecoverInterruptedWorkflowsStartupTask>()
 0229            .AddSingleton<IIngressSource, IngressSources.InternalBookmarkQueueIngressSource>()
 0230            .AddTransient<CShells.Lifecycle.IShellInitializer, Lifecycle.InitializePauseStateShellInitializer>()
 0231
 0232            // Core.
 0233            .AddScoped<ITriggerIndexer, TriggerIndexer>()
 0234            .AddScoped<IWorkflowInstanceFactory, WorkflowInstanceFactory>()
 0235            .AddScoped<IWorkflowHostFactory, WorkflowHostFactory>()
 0236            .AddScoped<IBackgroundActivityInvoker, BackgroundActivityInvoker>()
 0237            .AddScoped(WorkflowRuntime)
 0238            .AddScoped(WorkflowDispatcher)
 0239            .AddScoped(StimulusDispatcher)
 0240            .AddScoped(WorkflowCancellationDispatcher)
 0241            .AddScoped(RunTaskDispatcher)
 0242            .AddScoped(ActivityExecutionLogSink)
 0243            .AddScoped(WorkflowExecutionLogSink)
 0244            .AddSingleton(BackgroundActivityScheduler)
 0245            .AddSingleton<RandomLongIdentityGenerator>()
 0246            .AddSingleton<IBookmarkQueueSignaler, BookmarkQueueSignaler>()
 0247            .AddScoped(BookmarkQueueWorker)
 0248            .AddScoped<IBookmarkManager, DefaultBookmarkManager>()
 0249            .AddScoped<IActivityExecutionManager, DefaultActivityExecutionManager>()
 0250            .AddScoped<IActivityExecutionStatsService, ActivityExecutionStatsService>()
 0251            .AddScoped<IActivityExecutionMapper, DefaultActivityExecutionMapper>()
 0252            .AddScoped<IWorkflowDefinitionStorePopulator, DefaultWorkflowDefinitionStorePopulator>()
 0253            .AddScoped<IRegistriesPopulator, DefaultRegistriesPopulator>()
 0254            .AddScoped<IWorkflowDefinitionsRefresher, WorkflowDefinitionsRefresher>()
 0255            .AddScoped<IWorkflowDefinitionsReloader, WorkflowDefinitionsReloader>()
 0256            .AddScoped<IWorkflowRegistry, DefaultWorkflowRegistry>()
 0257            .AddScoped<IWorkflowMatcher, WorkflowMatcher>()
 0258            .AddScoped<IWorkflowInvoker, WorkflowInvoker>()
 0259            .AddScoped<IStimulusSender, StimulusSender>()
 0260            .AddScoped<ITriggerBoundWorkflowService, TriggerBoundWorkflowService>()
 0261            .AddScoped<IBookmarkBoundWorkflowService, BookmarkBoundWorkflowService>()
 0262            .AddScoped<ITaskReporter, TaskReporter>()
 0263            .AddScoped<SynchronousTaskDispatcher>()
 0264            .AddScoped<BackgroundTaskDispatcher>()
 0265            .AddScoped<StoreActivityExecutionLogSink>()
 0266            .AddScoped<StoreWorkflowExecutionLogSink>()
 0267            .AddScoped<DispatchWorkflowCommandHandler>()
 0268            .AddScoped<IEventPublisher, EventPublisher>()
 0269            .AddScoped<IBookmarkUpdater, BookmarkUpdater>()
 0270            .AddScoped<IBookmarksPersister, BookmarksPersister>()
 0271            .AddScoped<IBookmarkResumer, BookmarkResumer>()
 0272            .AddScoped<IBookmarkQueue, StoreBookmarkQueue>()
 0273            .AddScoped<IBookmarkQueueDeadLetterManager, BookmarkQueueDeadLetterManager>()
 0274            .AddScoped<WorkflowResumer>()
 0275            .AddScoped<BookmarkQueueWorker>()
 0276            .AddScoped(WorkflowResumer)
 0277            .AddScoped<ITriggerInvoker, TriggerInvoker>()
 0278            .AddScoped<IWorkflowCanceler, WorkflowCanceler>()
 0279            .AddScoped<IWorkflowCancellationService, WorkflowCancellationService>()
 0280            .AddScoped<IWorkflowActivationStrategyEvaluator, DefaultWorkflowActivationStrategyEvaluator>()
 0281            .AddScoped<IWorkflowStarter, DefaultWorkflowStarter>()
 0282            .AddScoped<IWorkflowRestarter, DefaultWorkflowRestarter>()
 0283            .AddScoped<IBookmarkQueuePurger, DefaultBookmarkQueuePurger>()
 0284            .AddSingleton<IWorkflowDispatchOutboxAccessor, WorkflowDispatchOutboxAccessor>()
 0285            .AddScoped<ILogRecordExtractor<WorkflowExecutionLogRecord>, WorkflowExecutionLogRecordExtractor>()
 0286            .AddScoped<IActivityPropertyLogPersistenceEvaluator, ActivityPropertyLogPersistenceEvaluator>()
 0287            .AddScoped<IBookmarkQueueProcessor, BookmarkQueueProcessor>()
 0288            .AddScoped<WorkflowCommitNotificationBuffer>()
 0289            .AddScoped<IWorkflowCommitNotificationBuffer>(sp => sp.GetRequiredService<WorkflowCommitNotificationBuffer>(
 0290            .AddScoped<INotificationSender, WorkflowCommitNotificationSender>()
 0291            .AddScoped<IWorkflowCommitTransaction, NoopWorkflowCommitTransaction>()
 0292            .AddScoped<DefaultCommitStateHandler>()
 0293            // Decorator: disposes the execution cycle handle AFTER the workflow runner's terminal commit has persisted 
 0294            // so the drain orchestrator's force-cancel path can sequence its Interrupted write to land last.
 0295            .AddScoped<ICommitStateHandler, ExecutionCycleAwareCommitStateHandler>()
 0296            .AddScoped<WorkflowHeartbeatGeneratorFactory>()
 0297
 0298            // Deprecated services.
 0299            .AddScoped<IWorkflowInbox, StimulusProxyWorkflowInbox>()
 0300
 0301            // Stores.
 0302            .AddScoped(BookmarkStore)
 0303            .AddScoped(BookmarkQueueStore)
 0304            .AddScoped(BookmarkQueueDeadLetterStore)
 0305            .AddScoped(TriggerStore)
 0306            .AddScoped(WorkflowExecutionLogStore)
 0307            .AddScoped(ActivityExecutionLogStore)
 0308
 0309            // Lazy services.
 0310            .AddScoped<Func<IEnumerable<IWorkflowsProvider>>>(sp => sp.GetServices<IWorkflowsProvider>)
 0311            .AddScoped<Func<IEnumerable<IWorkflowMaterializer>>>(sp => sp.GetServices<IWorkflowMaterializer>)
 0312
 0313            // Noop stores.
 0314            .AddScoped<MemoryWorkflowExecutionLogStore>()
 0315            .AddScoped<MemoryActivityExecutionStore>()
 0316
 0317            // Memory stores.
 0318            .AddMemoryStore<StoredBookmark, MemoryBookmarkStore>()
 0319            .AddMemoryStore<StoredTrigger, MemoryTriggerStore>()
 0320            .AddMemoryStore<BookmarkQueueItem, MemoryBookmarkQueueStore>()
 0321            .AddMemoryStore<BookmarkQueueDeadLetterItem, MemoryBookmarkQueueDeadLetterStore>()
 0322            .AddMemoryStore<WorkflowExecutionLogRecord, MemoryWorkflowExecutionLogStore>()
 0323            .AddMemoryStore<ActivityExecutionRecord, MemoryActivityExecutionStore>()
 0324
 0325            // Startup tasks, background tasks, and recurring tasks.
 0326            .AddStartupTask<PopulateRegistriesStartupTask>()
 0327            .AddRecurringTask<TriggerBookmarkQueueRecurringTask>(TimeSpan.FromMinutes(1))
 0328            .AddRecurringTask<PurgeBookmarkQueueRecurringTask>(TimeSpan.FromSeconds(10))
 0329            .AddRecurringTask<RestartInterruptedWorkflowsTask>(TimeSpan.FromMinutes(5)) // Same default as the workflow 
 0330            .AddRecurringTask<ProcessWorkflowDispatchOutboxRecurringTask>(TimeSpan.FromSeconds(10))
 0331
 0332            // Distributed locking.
 0333            .AddSingleton(DistributedLockProvider)
 0334
 0335            // Workflow providers.
 0336            .AddWorkflowsProvider<ClrWorkflowsProvider>()
 0337
 0338            // UI property handlers.
 0339            .AddScoped<IPropertyUIHandler, DispatcherChannelOptionsProvider>()
 0340
 0341            // Domain handlers.
 0342            .AddCommandHandler<DispatchWorkflowCommandHandler>()
 0343            .AddCommandHandler<DispatchStimulusCommandHandler>()
 0344            .AddCommandHandler<CancelWorkflowsCommandHandler>()
 0345            .AddNotificationHandler<ResumeDispatchWorkflowActivity>()
 0346            .AddNotificationHandler<ResumeBulkDispatchWorkflowActivity>()
 0347            .AddNotificationHandler<ProcessWorkflowDispatchOutbox>()
 0348            .AddNotificationHandler<ResumeExecuteWorkflowActivity>()
 0349            .AddNotificationHandler<IndexTriggers>()
 0350            .AddNotificationHandler<CancelBackgroundActivities>()
 0351            .AddNotificationHandler<DeleteBookmarks>()
 0352            .AddNotificationHandler<DeleteTriggers>()
 0353            .AddNotificationHandler<DeleteActivityExecutionLogRecords>()
 0354            .AddNotificationHandler<DeleteWorkflowExecutionLogRecords>()
 0355            .AddNotificationHandler<RefreshActivityRegistry>()
 0356            .AddNotificationHandler<SignalBookmarkQueueWorker>()
 0357            .AddNotificationHandler<EvaluateParentLogPersistenceModes>()
 0358            .AddNotificationHandler<CaptureActivityExecutionState>()
 0359            .AddNotificationHandler<ValidateWorkflowRequestHandler>()
 0360
 0361            // Workflow activation strategies.
 0362            .AddScoped<IWorkflowActivationStrategy, SingletonStrategy>()
 0363            .AddScoped<IWorkflowActivationStrategy, CorrelatedSingletonStrategy>()
 0364            .AddScoped<IWorkflowActivationStrategy, CorrelationStrategy>()
 0365            ;
 366
 0367        services.TryAddScoped<IWorkflowDispatchOutbox>(sp => ActivatorUtilities.CreateInstance<WorkflowDispatchOutbox>(s
 0368        services.TryAddScoped(WorkflowDispatchOutboxStore);
 0369        services.TryAddScoped<IWorkflowDispatchOutboxProcessor, WorkflowDispatchOutboxProcessor>();
 0370    }
 371
 372    private void RegisterWorkflowTypeAliases(SerializationTypeOptions options)
 373    {
 2374        WorkflowRuntimeTypeAliasRegistrar.Register(options, GetRegisteredWorkflowTypes());
 2375    }
 376
 377    private IEnumerable<Type> GetRegisteredWorkflowTypes()
 378    {
 2379        return WorkflowTypes
 7380            .Concat(Workflows.Keys.Select(TryResolveWorkflowType).Where(type => type != null).Select(type => type!))
 2381            .Distinct();
 382    }
 383
 384    private static Type? TryResolveWorkflowType(string typeName)
 385    {
 386        Type? type;
 387
 388        try
 389        {
 5390            type = Type.GetType(typeName, false);
 5391        }
 0392        catch (Exception e) when (e is ArgumentException or FileLoadException or FileNotFoundException or TypeLoadExcept
 393        {
 0394            return null;
 395        }
 396
 5397        return type != null && typeof(IWorkflow).IsAssignableFrom(type) && type is { IsAbstract: false, IsInterface: fal
 5398            ? type
 5399            : null;
 0400    }
 401}