Refactor expression descriptors and remove unnecessary async calls
This commit refactors how expression descriptors are created and retrieved across Elsa project. The asynchronous methods have been simplified to synchronous ones removing unnecessary `ValueTask` returns. Additionally, `IExpressionDescriptorRegistryPopulator` has been removed resulting in less complexity and better performance.
This commit is contained in:
parent
3d68207547
commit
6ff6cc6826
|
|
@ -92,7 +92,7 @@ Open Program.cs and replace its contents with the following code:
|
|||
```csharp
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Workflows.Core.Activities;
|
||||
using Elsa.Workflows.Core.Services;
|
||||
using Elsa.Workflows.Core.Contracts;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
// Set up the service container.
|
||||
|
|
|
|||
|
|
@ -10,18 +10,14 @@ internal class CSharpExpressionDescriptorProvider : IExpressionDescriptorProvide
|
|||
{
|
||||
private const string TypeName = "CSharp";
|
||||
|
||||
public ValueTask<IEnumerable<ExpressionDescriptor>> GetDescriptorsAsync(CancellationToken cancellationToken = default)
|
||||
public IEnumerable<ExpressionDescriptor> GetDescriptors()
|
||||
{
|
||||
var descriptor = CreateCSharpDescriptor();
|
||||
|
||||
return ValueTask.FromResult<IEnumerable<ExpressionDescriptor>>(new[] { descriptor });
|
||||
yield return new()
|
||||
{
|
||||
Type = TypeName,
|
||||
DisplayName = "C#",
|
||||
Properties = new { MonacoLanguage = "csharp" }.ToDictionary(),
|
||||
HandlerFactory = ActivatorUtilities.GetServiceOrCreateInstance<CSharpExpressionHandler>
|
||||
};
|
||||
}
|
||||
|
||||
private static ExpressionDescriptor CreateCSharpDescriptor() => new()
|
||||
{
|
||||
Type = TypeName,
|
||||
DisplayName = "C#",
|
||||
Properties = new { MonacoLanguage = "csharp" }.ToDictionary(),
|
||||
HandlerFactory = ActivatorUtilities.GetServiceOrCreateInstance<CSharpExpressionHandler>
|
||||
};
|
||||
}
|
||||
|
|
@ -10,5 +10,5 @@ public interface IExpressionDescriptorProvider
|
|||
/// <summary>
|
||||
/// Gets the descriptors for the expression syntaxes supported by this provider.
|
||||
/// </summary>
|
||||
ValueTask<IEnumerable<ExpressionDescriptor>> GetDescriptorsAsync(CancellationToken cancellationToken = default);
|
||||
IEnumerable<ExpressionDescriptor> GetDescriptors();
|
||||
}
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
namespace Elsa.Expressions.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// Populates the expression descriptor registry.
|
||||
/// </summary>
|
||||
public interface IExpressionDescriptorRegistryPopulator
|
||||
{
|
||||
/// <summary>
|
||||
/// Populates the expression descriptor registry.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
ValueTask PopulateRegistryAsync(CancellationToken cancellationToken = default);
|
||||
}
|
||||
// namespace Elsa.Expressions.Contracts;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Populates the expression descriptor registry.
|
||||
// /// </summary>
|
||||
// public interface IExpressionDescriptorRegistryPopulator
|
||||
// {
|
||||
// /// <summary>
|
||||
// /// Populates the expression descriptor registry.
|
||||
// /// </summary>
|
||||
// /// <param name="cancellationToken">The cancellation token.</param>
|
||||
// ValueTask PopulateRegistryAsync(CancellationToken cancellationToken = default);
|
||||
// }
|
||||
|
|
@ -2,7 +2,6 @@ using Elsa.Expressions.Contracts;
|
|||
using Elsa.Expressions.Models;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.JavaScript.Expressions;
|
||||
using Elsa.Workflows.Core.Contracts;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Elsa.JavaScript.Providers;
|
||||
|
|
@ -11,18 +10,14 @@ internal class JavaScriptExpressionDescriptorProvider : IExpressionDescriptorPro
|
|||
{
|
||||
private const string TypeName = "JavaScript";
|
||||
|
||||
public ValueTask<IEnumerable<ExpressionDescriptor>> GetDescriptorsAsync(CancellationToken cancellationToken = default)
|
||||
public IEnumerable<ExpressionDescriptor> GetDescriptors()
|
||||
{
|
||||
var javaScript = CreateJavaScriptDescriptor();
|
||||
|
||||
return ValueTask.FromResult<IEnumerable<ExpressionDescriptor>>(new[] { javaScript });
|
||||
yield return new()
|
||||
{
|
||||
Type = TypeName,
|
||||
DisplayName = "JavaScript",
|
||||
Properties = new { MonacoLanguage = "javascript" }.ToDictionary(),
|
||||
HandlerFactory = ActivatorUtilities.GetServiceOrCreateInstance<JavaScriptExpressionHandler>
|
||||
};
|
||||
}
|
||||
|
||||
private static ExpressionDescriptor CreateJavaScriptDescriptor() => new()
|
||||
{
|
||||
Type = TypeName,
|
||||
DisplayName = "JavaScript",
|
||||
Properties = new { MonacoLanguage = "javascript" }.ToDictionary(),
|
||||
HandlerFactory = ActivatorUtilities.GetServiceOrCreateInstance<JavaScriptExpressionHandler>
|
||||
};
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@ using Elsa.Expressions.Contracts;
|
|||
using Elsa.Expressions.Models;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Liquid.Expressions;
|
||||
using Elsa.Workflows.Core.Contracts;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Elsa.Liquid.Providers;
|
||||
|
|
@ -16,26 +15,16 @@ public class LiquidExpressionDescriptorProvider : IExpressionDescriptorProvider
|
|||
/// Gets the name of the expression type.
|
||||
/// </summary>
|
||||
public const string TypeName = "Liquid";
|
||||
private readonly IIdentityGenerator _identityGenerator;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LiquidExpressionDescriptorProvider"/> class.
|
||||
/// </summary>
|
||||
public LiquidExpressionDescriptorProvider(IIdentityGenerator identityGenerator) => _identityGenerator = identityGenerator;
|
||||
|
||||
/// <inheritdoc />
|
||||
public ValueTask<IEnumerable<ExpressionDescriptor>> GetDescriptorsAsync(CancellationToken cancellationToken = default)
|
||||
public IEnumerable<ExpressionDescriptor> GetDescriptors()
|
||||
{
|
||||
var liquidDescriptor = CreateLiquidDescriptor();
|
||||
|
||||
return ValueTask.FromResult<IEnumerable<ExpressionDescriptor>>(new[] { liquidDescriptor });
|
||||
yield return new()
|
||||
{
|
||||
Type = TypeName,
|
||||
DisplayName = "Liquid",
|
||||
Properties = new { MonacoLanguage = "liquid" }.ToDictionary(),
|
||||
HandlerFactory = ActivatorUtilities.GetServiceOrCreateInstance<LiquidExpressionHandler>
|
||||
};
|
||||
}
|
||||
|
||||
private ExpressionDescriptor CreateLiquidDescriptor() => new()
|
||||
{
|
||||
Type = TypeName,
|
||||
DisplayName = "Liquid",
|
||||
Properties = new { MonacoLanguage = "liquid" }.ToDictionary(),
|
||||
HandlerFactory = ActivatorUtilities.GetServiceOrCreateInstance<LiquidExpressionHandler>
|
||||
};
|
||||
}
|
||||
|
|
@ -9,19 +9,15 @@ namespace Elsa.Python.Providers;
|
|||
internal class PythonExpressionDescriptorProvider : IExpressionDescriptorProvider
|
||||
{
|
||||
private const string TypeName = "Python";
|
||||
|
||||
public ValueTask<IEnumerable<ExpressionDescriptor>> GetDescriptorsAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
var javaScript = CreatePythonDescriptor();
|
||||
|
||||
return ValueTask.FromResult<IEnumerable<ExpressionDescriptor>>(new[] { javaScript });
|
||||
public IEnumerable<ExpressionDescriptor> GetDescriptors()
|
||||
{
|
||||
yield return new()
|
||||
{
|
||||
Type = TypeName,
|
||||
DisplayName = "Python",
|
||||
Properties = new { MonacoLanguage = "python" }.ToDictionary(),
|
||||
HandlerFactory = ActivatorUtilities.GetServiceOrCreateInstance<PythonExpressionHandler>
|
||||
};
|
||||
}
|
||||
|
||||
private ExpressionDescriptor CreatePythonDescriptor() => new()
|
||||
{
|
||||
Type = TypeName,
|
||||
DisplayName = "Python",
|
||||
Properties = new { MonacoLanguage = "python" }.ToDictionary(),
|
||||
HandlerFactory = ActivatorUtilities.GetServiceOrCreateInstance<PythonExpressionHandler>
|
||||
};
|
||||
}
|
||||
|
|
@ -166,7 +166,6 @@ public class WorkflowManagementFeature : FeatureBase
|
|||
.AddSingleton<IActivityRegistryPopulator, ActivityRegistryPopulator>()
|
||||
.AddSingleton<IExpressionDescriptorRegistry, ExpressionDescriptorRegistry>()
|
||||
.AddSingleton<IExpressionDescriptorProvider, DefaultExpressionDescriptorProvider>()
|
||||
.AddSingleton<IExpressionDescriptorRegistryPopulator, ExpressionDescriptorRegistryPopulator>()
|
||||
.AddSingleton<ISerializationOptionsConfigurator, SerializationOptionsConfigurator>()
|
||||
.AddSingleton<IWorkflowMaterializer, ClrWorkflowMaterializer>()
|
||||
.AddSingleton<IWorkflowMaterializer, JsonWorkflowMaterializer>()
|
||||
|
|
|
|||
|
|
@ -12,15 +12,13 @@ namespace Elsa.Workflows.Management.Providers;
|
|||
public class DefaultExpressionDescriptorProvider : IExpressionDescriptorProvider
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public ValueTask<IEnumerable<ExpressionDescriptor>> GetDescriptorsAsync(CancellationToken cancellationToken = default)
|
||||
public IEnumerable<ExpressionDescriptor> GetDescriptors()
|
||||
{
|
||||
var literal = CreateLiteralDescriptor();
|
||||
var @object = CreateObjectDescriptor();
|
||||
var json = CreateJsonDescriptor();
|
||||
var @delegate = CreateDelegateDescriptor();
|
||||
var variable = CreateVariableDescriptor();
|
||||
|
||||
return ValueTask.FromResult<IEnumerable<ExpressionDescriptor>>(new[] { literal, @object, json, @delegate, variable });
|
||||
yield return CreateLiteralDescriptor();
|
||||
yield return CreateObjectDescriptor();
|
||||
yield return CreateJsonDescriptor();
|
||||
yield return CreateDelegateDescriptor();
|
||||
yield return CreateVariableDescriptor();
|
||||
}
|
||||
|
||||
private ExpressionDescriptor CreateLiteralDescriptor() => CreateDescriptor<LiteralExpressionHandler>("Literal", "Literal", isBrowsable: false);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,16 @@ namespace Elsa.Workflows.Management.Services;
|
|||
public class ExpressionDescriptorRegistry : IExpressionDescriptorRegistry
|
||||
{
|
||||
private readonly IDictionary<string, ExpressionDescriptor> _expressionSyntaxDescriptors = new Dictionary<string, ExpressionDescriptor>();
|
||||
|
||||
/// Represents a registry of expression descriptors.
|
||||
public ExpressionDescriptorRegistry(IEnumerable<IExpressionDescriptorProvider> providers)
|
||||
{
|
||||
foreach (var provider in providers)
|
||||
{
|
||||
var descriptors = provider.GetDescriptors();
|
||||
AddRange(descriptors);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Add(ExpressionDescriptor descriptor) => _expressionSyntaxDescriptors[descriptor.Type] = descriptor;
|
||||
|
|
|
|||
|
|
@ -1,29 +1,29 @@
|
|||
using Elsa.Expressions.Contracts;
|
||||
|
||||
namespace Elsa.Workflows.Management.Services;
|
||||
|
||||
/// <inheritdoc />
|
||||
public class ExpressionDescriptorRegistryPopulator : IExpressionDescriptorRegistryPopulator
|
||||
{
|
||||
private readonly IEnumerable<IExpressionDescriptorProvider> _providers;
|
||||
private readonly IExpressionDescriptorRegistry _registry;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ExpressionDescriptorRegistryPopulator"/> class.
|
||||
/// </summary>
|
||||
public ExpressionDescriptorRegistryPopulator(IEnumerable<IExpressionDescriptorProvider> providers, IExpressionDescriptorRegistry registry)
|
||||
{
|
||||
_providers = providers;
|
||||
_registry = registry;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async ValueTask PopulateRegistryAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
foreach (var provider in _providers)
|
||||
{
|
||||
var descriptors = await provider.GetDescriptorsAsync(cancellationToken);
|
||||
_registry.AddRange(descriptors);
|
||||
}
|
||||
}
|
||||
}
|
||||
// using Elsa.Expressions.Contracts;
|
||||
//
|
||||
// namespace Elsa.Workflows.Management.Services;
|
||||
//
|
||||
// /// <inheritdoc />
|
||||
// public class ExpressionDescriptorRegistryPopulator : IExpressionDescriptorRegistryPopulator
|
||||
// {
|
||||
// private readonly IEnumerable<IExpressionDescriptorProvider> _providers;
|
||||
// private readonly IExpressionDescriptorRegistry _registry;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Initializes a new instance of the <see cref="ExpressionDescriptorRegistryPopulator"/> class.
|
||||
// /// </summary>
|
||||
// public ExpressionDescriptorRegistryPopulator(IEnumerable<IExpressionDescriptorProvider> providers, IExpressionDescriptorRegistry registry)
|
||||
// {
|
||||
// _providers = providers;
|
||||
// _registry = registry;
|
||||
// }
|
||||
//
|
||||
// /// <inheritdoc />
|
||||
// public async ValueTask PopulateRegistryAsync(CancellationToken cancellationToken)
|
||||
// {
|
||||
// foreach (var provider in _providers)
|
||||
// {
|
||||
// var descriptors = await provider.GetDescriptorsAsync(cancellationToken);
|
||||
// _registry.AddRange(descriptors);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
|
@ -10,27 +10,19 @@ public class DefaultRegistriesPopulator : IRegistriesPopulator
|
|||
{
|
||||
private readonly IWorkflowDefinitionStorePopulator _workflowDefinitionStorePopulator;
|
||||
private readonly IActivityRegistryPopulator _activityRegistryPopulator;
|
||||
private readonly IExpressionDescriptorRegistryPopulator _expressionDescriptorRegistryPopulator;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PopulateRegistriesHostedService"/> class.
|
||||
/// </summary>
|
||||
public DefaultRegistriesPopulator(
|
||||
IWorkflowDefinitionStorePopulator workflowDefinitionStorePopulator,
|
||||
IActivityRegistryPopulator activityRegistryPopulator,
|
||||
IExpressionDescriptorRegistryPopulator expressionDescriptorRegistryPopulator)
|
||||
public DefaultRegistriesPopulator(IWorkflowDefinitionStorePopulator workflowDefinitionStorePopulator, IActivityRegistryPopulator activityRegistryPopulator)
|
||||
{
|
||||
_workflowDefinitionStorePopulator = workflowDefinitionStorePopulator;
|
||||
_activityRegistryPopulator = activityRegistryPopulator;
|
||||
_expressionDescriptorRegistryPopulator = expressionDescriptorRegistryPopulator;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task PopulateAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
// Stage 0: Populate the expression syntax registry.
|
||||
await _expressionDescriptorRegistryPopulator.PopulateRegistryAsync(cancellationToken);
|
||||
|
||||
// Stage 1: Populate the activity registry.
|
||||
// Because workflow definitions can be used as activities, we need to make sure that the activity registry is populated before we populate the workflow definition store.
|
||||
await _activityRegistryPopulator.PopulateRegistryAsync(cancellationToken);
|
||||
|
|
|
|||
Loading…
Reference in a new issue