elsa-core/src/common/Elsa.Testing.Shared/ServiceProviderExtensions.cs

126 lines
5.6 KiB
C#
Raw Normal View History

using Elsa.Common.Models;
Add a more generic UIHandler to customize how inputAttributes can be handle by UI (#4688) * add a more generic UIHandler to customize how inputAttributes can be handle by the ui * Add IPropertyUIHandlerResolver and update PropertyUIHandlerResolver Introduced a new interface, IPropertyUIHandlerResolver, to resolve UI options for a property. Refactored PropertyUIHandlerResolver to implement this interface and removed the unnecessary partial class structure. Also, cleaned up some unnecessary usings in various files for better code organization. * Refactor variable name and description in InputDescriptor The 'uISpecifications' variable in the InputDescriptor model is renamed to 'uiSpecifications' for better readability. Additionally, the associated comment was revised to explain that the dictionary is used by the UI. * "Refactor codebase for improved organization and cleaner architecture" The codebase has been significantly refactored, moving several classes to more appropriate namespaces for improved organization and cleaner architecture. This includes shifting UI hint handlers, activities, and memory-related components, amongst others. The changes should improve code readability and maintainability, but as this is a broad refactoring effort, thorough regression testing is advised. * Add CheckList UIHint with associated handler and provider This update introduces a new UIHint called CheckList to the Elsa.Workflows.Core. This includes the necessary handler and provider classes. The handler is registered in the WorkflowsFeature.cs, and the CheckList UIHint key has been added to the InputUIHints.cs. Various associated files have been created in both the Elsa.Api.Client and Elsa.Workflows.Core project to support this new UIHint. --------- Co-authored-by: Jérémie DEVILLARD <jdevillard@users.noreply.github.com> Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
2023-12-26 17:56:29 +00:00
using Elsa.Workflows;
using Elsa.Workflows.Contracts;
using Elsa.Workflows.Management.Contracts;
using Elsa.Workflows.Management.Entities;
using Elsa.Workflows.Management.Models;
Add a more generic UIHandler to customize how inputAttributes can be handle by UI (#4688) * add a more generic UIHandler to customize how inputAttributes can be handle by the ui * Add IPropertyUIHandlerResolver and update PropertyUIHandlerResolver Introduced a new interface, IPropertyUIHandlerResolver, to resolve UI options for a property. Refactored PropertyUIHandlerResolver to implement this interface and removed the unnecessary partial class structure. Also, cleaned up some unnecessary usings in various files for better code organization. * Refactor variable name and description in InputDescriptor The 'uISpecifications' variable in the InputDescriptor model is renamed to 'uiSpecifications' for better readability. Additionally, the associated comment was revised to explain that the dictionary is used by the UI. * "Refactor codebase for improved organization and cleaner architecture" The codebase has been significantly refactored, moving several classes to more appropriate namespaces for improved organization and cleaner architecture. This includes shifting UI hint handlers, activities, and memory-related components, amongst others. The changes should improve code readability and maintainability, but as this is a broad refactoring effort, thorough regression testing is advised. * Add CheckList UIHint with associated handler and provider This update introduces a new UIHint called CheckList to the Elsa.Workflows.Core. This includes the necessary handler and provider classes. The handler is registered in the WorkflowsFeature.cs, and the CheckList UIHint key has been added to the InputUIHints.cs. Various associated files have been created in both the Elsa.Api.Client and Elsa.Workflows.Core project to support this new UIHint. --------- Co-authored-by: Jérémie DEVILLARD <jdevillard@users.noreply.github.com> Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
2023-12-26 17:56:29 +00:00
using Elsa.Workflows.Models;
using Elsa.Workflows.Options;
using Elsa.Workflows.Runtime.Contracts;
using Elsa.Workflows.Runtime.Options;
Add a more generic UIHandler to customize how inputAttributes can be handle by UI (#4688) * add a more generic UIHandler to customize how inputAttributes can be handle by the ui * Add IPropertyUIHandlerResolver and update PropertyUIHandlerResolver Introduced a new interface, IPropertyUIHandlerResolver, to resolve UI options for a property. Refactored PropertyUIHandlerResolver to implement this interface and removed the unnecessary partial class structure. Also, cleaned up some unnecessary usings in various files for better code organization. * Refactor variable name and description in InputDescriptor The 'uISpecifications' variable in the InputDescriptor model is renamed to 'uiSpecifications' for better readability. Additionally, the associated comment was revised to explain that the dictionary is used by the UI. * "Refactor codebase for improved organization and cleaner architecture" The codebase has been significantly refactored, moving several classes to more appropriate namespaces for improved organization and cleaner architecture. This includes shifting UI hint handlers, activities, and memory-related components, amongst others. The changes should improve code readability and maintainability, but as this is a broad refactoring effort, thorough regression testing is advised. * Add CheckList UIHint with associated handler and provider This update introduces a new UIHint called CheckList to the Elsa.Workflows.Core. This includes the necessary handler and provider classes. The handler is registered in the WorkflowsFeature.cs, and the CheckList UIHint key has been added to the InputUIHints.cs. Various associated files have been created in both the Elsa.Api.Client and Elsa.Workflows.Core project to support this new UIHint. --------- Co-authored-by: Jérémie DEVILLARD <jdevillard@users.noreply.github.com> Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
2023-12-26 17:56:29 +00:00
using Elsa.Workflows.State;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
namespace Elsa.Testing.Shared;
/// <summary>
/// Provides extension methods for <see cref="IServiceProvider"/>.
/// </summary>
[PublicAPI]
public static class ServiceProviderExtensions
{
/// <summary>
/// Updates the registries.
/// </summary>
/// <param name="services">The services.</param>
public static Task PopulateRegistriesAsync(this IServiceProvider services)
{
var registriesPopulator = services.GetRequiredService<IRegistriesPopulator>();
return registriesPopulator.PopulateAsync();
}
/// <summary>
/// Imports a workflow definition from a file.
/// </summary>
/// <param name="services">The services.</param>
/// <param name="fileName">The file name.</param>
/// <returns>The workflow definition.</returns>
public static async Task<WorkflowDefinition> ImportWorkflowDefinitionAsync(this IServiceProvider services, string fileName)
{
var json = await File.ReadAllTextAsync(fileName);
var serializer = services.GetRequiredService<IActivitySerializer>();
var model = serializer.Deserialize<WorkflowDefinitionModel>(json);
var workflowDefinitionRequest = new SaveWorkflowDefinitionRequest
{
Model = model,
Publish = true
};
var workflowDefinitionImporter = services.GetRequiredService<IWorkflowDefinitionImporter>();
var result = await workflowDefinitionImporter.ImportAsync(workflowDefinitionRequest);
return result.WorkflowDefinition;
}
/// <summary>
/// Runs a workflow until its end, automatically resuming any bookmark it encounters.
/// </summary>
/// <param name="services">The services.</param>
/// <param name="workflowDefinitionId">The ID of the workflow definition.</param>
/// <param name="input">An optional dictionary of input values.</param>
/// <returns>The workflow state.</returns>
public static async Task<WorkflowState> RunWorkflowUntilEndAsync(this IServiceProvider services, string workflowDefinitionId, IDictionary<string, object>? input = default)
{
var startWorkflowOptions = new StartWorkflowRuntimeOptions
{
Input = input,
VersionOptions = VersionOptions.Published
};
var workflowRuntime = services.GetRequiredService<IWorkflowRuntime>();
var result = await workflowRuntime.StartWorkflowAsync(workflowDefinitionId, startWorkflowOptions);
var bookmarks = new Stack<Bookmark>(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))!;
}
/// <summary>
/// Runs a workflow until its end, automatically resuming any bookmark it encounters.
/// </summary>
public static async Task<WorkflowState> RunWorkflowUntilEndAsync<TWorkflow>(this IServiceProvider services, IDictionary<string, object>? input = default) where TWorkflow : IWorkflow
{
var workflowDefinitionId = typeof(TWorkflow).Name;
return await services.RunWorkflowUntilEndAsync(workflowDefinitionId, input);
}
2023-10-17 22:10:48 +00:00
/// <summary>
/// Runs the specified activity.
/// </summary>
/// <param name="services">The service provider.</param>
/// <param name="activity">The activity to run.</param>
/// <param name="cancellationToken">An optional cancellation token.</param>
/// <returns>The result of running the activity.</returns>
public static async Task<RunWorkflowResult> RunActivityAsync(this IServiceProvider services, IActivity activity, CancellationToken cancellationToken = default)
{
await services.PopulateRegistriesAsync();
2023-10-17 22:10:48 +00:00
var workflowRunner = services.GetRequiredService<IWorkflowRunner>();
var result = await workflowRunner.RunAsync(activity, cancellationToken: cancellationToken);
return result;
}
/// <summary>
/// Runs the specified activity.
/// </summary>
/// <param name="services">The service provider.</param>
/// <param name="activity">The activity to run.</param>
/// <param name="options">An set of options.</param>
/// <param name="cancellationToken">An optional cancellation token.</param>
/// <returns>The result of running the activity.</returns>
public static async Task<RunWorkflowResult> RunActivityAsync(this IServiceProvider services, IActivity activity, RunWorkflowOptions options, CancellationToken cancellationToken = default)
{
var workflowRunner = services.GetRequiredService<IWorkflowRunner>();
var result = await workflowRunner.RunAsync(activity, options, cancellationToken);
return result;
}
}