using Elsa.Common.Models; using Elsa.Workflows.Core; using Elsa.Workflows.Core.Contracts; using Elsa.Workflows.Core.Models; using Elsa.Workflows.Core.State; using Elsa.Workflows.Management.Contracts; using Elsa.Workflows.Management.Entities; using Elsa.Workflows.Management.Models; using Elsa.Workflows.Runtime.Contracts; using Elsa.Workflows.Runtime.Requests; using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; namespace Elsa.Testing.Shared; /// /// Provides extension methods for . /// [PublicAPI] public static class ServiceProviderExtensions { /// /// Updates the registries. /// /// The services. public static async Task PopulateRegistriesAsync(this IServiceProvider services) { var registriesPopulator = services.GetRequiredService(); await registriesPopulator.PopulateAsync(); } /// /// Imports a workflow definition from a file. /// /// The services. /// The file name. /// The workflow definition. public static async Task ImportWorkflowDefinitionAsync(this IServiceProvider services, string fileName) { var json = await File.ReadAllTextAsync(fileName); var serializer = services.GetRequiredService(); var model = serializer.Deserialize(json); var workflowDefinitionRequest = new SaveWorkflowDefinitionRequest { Model = model, Publish = true }; var workflowDefinitionImporter = services.GetRequiredService(); var result = await workflowDefinitionImporter.ImportAsync(workflowDefinitionRequest); return result.WorkflowDefinition; } /// /// Runs a workflow until its end, automatically resuming any bookmark it encounters. /// /// The services. /// The ID of the workflow definition. /// An optional dictionary of input values. /// The workflow state. public static async Task RunWorkflowUntilEndAsync(this IServiceProvider services, string workflowDefinitionId, IDictionary? input = default) { var startWorkflowOptions = new StartWorkflowRuntimeOptions(null, input, VersionOptions.Published); var workflowRuntime = services.GetRequiredService(); var result = await workflowRuntime.StartWorkflowAsync(workflowDefinitionId, startWorkflowOptions); var bookmarks = new Stack(result.Bookmarks); // Continue resuming the workflow for as long as there are bookmarks to resume and the workflow is not Finished. while (result.Status != WorkflowStatus.Finished && bookmarks.TryPop(out var bookmark)) { var resumeOptions = new ResumeWorkflowRuntimeOptions(BookmarkId: bookmark.Id); var resumeResult = await workflowRuntime.ResumeWorkflowAsync(result.WorkflowInstanceId, resumeOptions); foreach (var newBookmark in resumeResult!.Bookmarks) bookmarks.Push(newBookmark); } // Return the workflow state. return (await workflowRuntime.ExportWorkflowStateAsync(result.WorkflowInstanceId))!; } /// /// Runs a workflow until its end, automatically resuming any bookmark it encounters. /// public static async Task RunWorkflowUntilEndAsync(this IServiceProvider services, IDictionary? input = default) where TWorkflow : IWorkflow { var workflowDefinitionId = typeof(TWorkflow).Name; return await services.RunWorkflowUntilEndAsync(workflowDefinitionId, input); } }