Improve JS result parsing with support for target type conversions

This commit is contained in:
Sipke Schoorstra 2021-05-25 13:24:01 +02:00
parent 0b10faad92
commit ca1db18bd7
4 changed files with 21 additions and 21 deletions

View file

@ -26,6 +26,8 @@ namespace Elsa.Scripting.JavaScript.Converters
case double:
{
var doubleValue = Convert.ToDouble(value);
// ReSharper disable once CompareOfFloatsByEqualityOperator
return doubleValue == Math.Truncate(doubleValue);
}
default:

View file

@ -33,6 +33,7 @@ namespace Elsa.Scripting.JavaScript.Handlers
// Global functions.
engine.SetValue("guid", (Func<string>) (() => Guid.NewGuid().ToString()));
engine.SetValue("parseGuid", (Func<string, Guid>) (Guid.Parse));
engine.SetValue("setVariable", (Action<string, object>) ((name, value) => activityExecutionContext.SetVariable(name, value)));
engine.SetValue("getVariable", (Func<string, object?>) (name => activityExecutionContext.GetVariable(name)));
engine.SetValue("getConfig", (Func<string, object?>) (name => _configuration.GetSection(name).Value));

View file

@ -5,7 +5,9 @@ namespace Elsa.Scripting.JavaScript.Services
{
public class JintEvaluationResultConverterFactory
{
readonly IServiceProvider serviceProvider;
private readonly IServiceProvider _serviceProvider;
public JintEvaluationResultConverterFactory(IServiceProvider serviceProvider) => this._serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
public IConvertsJintEvaluationResult GetConverter()
{
@ -13,7 +15,7 @@ namespace Elsa.Scripting.JavaScript.Services
// Builds a chain-of-responsibility service
// Note: The order in which these classes execute is bottom-to-top
service = GetConvertChangeTypeService();
service = GetPlainObjectService(service);
service = GetEnumerableConvertingService(service);
@ -24,30 +26,20 @@ namespace Elsa.Scripting.JavaScript.Services
return service;
}
static IConvertsJintEvaluationResult GetConvertChangeTypeService()
=> new ConvertChangeTypeResultConverter();
static IConvertsJintEvaluationResult GetConvertChangeTypeService() => new ConvertChangeTypeResultConverter();
static IConvertsJintEvaluationResult GetPlainObjectService(IConvertsJintEvaluationResult wrapped)
=> new PlainObjectResultConverter(wrapped);
static IConvertsJintEvaluationResult GetPlainObjectService(IConvertsJintEvaluationResult wrapped) => new PlainObjectResultConverter(wrapped);
IConvertsJintEvaluationResult GetEnumerableConvertingService(IConvertsJintEvaluationResult wrapped)
=> new EnumerableResultConverter(wrapped);
IConvertsJintEvaluationResult GetEnumerableConvertingService(IConvertsJintEvaluationResult wrapped) => new EnumerableResultConverter(wrapped);
IConvertsJintEvaluationResult GetExpandoConvertingService(IConvertsJintEvaluationResult wrapped)
{
var enumerableConverter = serviceProvider.GetRequiredService<IConvertsEnumerableToObject>();
var enumerableConverter = _serviceProvider.GetRequiredService<IConvertsEnumerableToObject>();
return new ExpandoObjectToDictionaryWhenNoDesiredTypeResultConverter(enumerableConverter, wrapped);
}
static IConvertsJintEvaluationResult GetTypeConverterConvertingService(IConvertsJintEvaluationResult wrapped)
=> new TypeConverterResultConverter(wrapped);
static IConvertsJintEvaluationResult GetNullConvertingService(IConvertsJintEvaluationResult wrapped)
=> new NullResultConverter(wrapped);
public JintEvaluationResultConverterFactory(IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
}
static IConvertsJintEvaluationResult GetTypeConverterConvertingService(IConvertsJintEvaluationResult wrapped) => new TypeConverterResultConverter(wrapped);
static IConvertsJintEvaluationResult GetNullConvertingService(IConvertsJintEvaluationResult wrapped) => new NullResultConverter(wrapped);
}
}

View file

@ -9,10 +9,15 @@ namespace Elsa.Scripting.JavaScript.Services
public object? ConvertToDesiredType(object? evaluationResult, Type desiredType)
{
var converter = TypeDescriptor.GetConverter(evaluationResult);
var converter = TypeDescriptor.GetConverter(evaluationResult!);
if (converter.CanConvertTo(desiredType))
return converter.ConvertTo(evaluationResult, desiredType);
return converter.ConvertTo(evaluationResult!, desiredType);
var targetConverter = TypeDescriptor.GetConverter(desiredType);
if (targetConverter.CanConvertFrom(evaluationResult!.GetType()))
return targetConverter.ConvertFrom(evaluationResult!);
return wrapped.ConvertToDesiredType(evaluationResult, desiredType);
}