using Elsa.Common.Models;
using Elsa.Workflows;
using Elsa.Workflows.Contracts;
using Elsa.Workflows.Management;
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.Parameters;
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.
/// An optional set of options to specify the version of the workflow definition to retrieve.
/// The workflow state.
public static async Task RunWorkflowUntilEndAsync(this IServiceProvider services,
string workflowDefinitionId,
IDictionary? input = default,
VersionOptions? versionOptions = default)
{
var workflowDefinitionService = services.GetRequiredService();
var workflowGraph = await workflowDefinitionService.FindWorkflowGraphAsync(workflowDefinitionId, versionOptions ?? VersionOptions.Published);
var workflowRuntime = services.GetRequiredService();
var workflowClient = await workflowRuntime.CreateClientAsync();
var response = await workflowClient.CreateAndRunInstanceAsync(new CreateAndRunWorkflowInstanceRequest
{
WorkflowDefinitionHandle = WorkflowDefinitionHandle.ByDefinitionVersionId(workflowGraph!.Workflow.Identity.Id),
Input = input
});
var bookmarkStore = services.GetRequiredService();
// Continue resuming the workflow for as long as there are bookmarks to resume and the workflow is not Finished.
while (response.Status != WorkflowStatus.Finished)
{
var bookmarks = (await bookmarkStore.FindManyAsync(new BookmarkFilter
{
WorkflowInstanceId = response.WorkflowInstanceId
})).ToList();
if (!bookmarks.Any())
break;
foreach (var bookmark in bookmarks)
{
var runRequest = new RunWorkflowInstanceRequest
{
BookmarkId = bookmark.Id
};
response = await workflowClient.RunInstanceAsync(runRequest);
}
}
// Return the workflow state.
return await workflowClient.ExportStateAsync();
}
///
/// 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.FindWorkflowDefinitionAsync(workflowDefinitionId, versionOptions);
return workflowDefinition!;
}
}