using Elsa.Common.Models;
using Elsa.Workflows;
using Elsa.Workflows.Contracts;
using Elsa.Workflows.Management.Contracts;
using Elsa.Workflows.Management.Entities;
using Elsa.Workflows.Management.Models;
using Elsa.Workflows.Models;
using Elsa.Workflows.Options;
using Elsa.Workflows.Runtime.Contracts;
using Elsa.Workflows.Runtime.Options;
using Elsa.Workflows.State;
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 Task PopulateRegistriesAsync(this IServiceProvider services)
{
var registriesPopulator = services.GetRequiredService();
return 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
{
Input = input,
VersionOptions = 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);
}
///
/// Runs the specified activity.
///
/// The service provider.
/// The activity to run.
/// An optional cancellation token.
/// The result of running the activity.
public static async Task RunActivityAsync(this IServiceProvider services, IActivity activity, CancellationToken cancellationToken = default)
{
await services.PopulateRegistriesAsync();
var workflowRunner = services.GetRequiredService();
var result = await workflowRunner.RunAsync(activity, cancellationToken: cancellationToken);
return result;
}
///
/// Runs the specified activity.
///
/// The service provider.
/// The activity to run.
/// An set of options.
/// An optional cancellation token.
/// The result of running the activity.
public static async Task RunActivityAsync(this IServiceProvider services, IActivity activity, RunWorkflowOptions options, CancellationToken cancellationToken = default)
{
var workflowRunner = services.GetRequiredService();
var result = await workflowRunner.RunAsync(activity, options, cancellationToken);
return result;
}
///
/// Retrieves a workflow definition by its ID.
///
/// The service provider.
/// The definition ID of the workflow definition.
/// Options to specify the version of the workflow definition to retrieve.
/// A cancellation token to cancel the operation.
/// The retrieved workflow definition.
public static async Task GetWorkflowDefinitionAsync(this IServiceProvider services, string workflowDefinitionId, VersionOptions versionOptions, CancellationToken cancellationToken = default)
{
var workflowDefinitionService = services.GetRequiredService();
var workflowDefinition = await workflowDefinitionService.FindAsync(workflowDefinitionId, versionOptions);
return workflowDefinition!;
}
}