Fix JsonObject type handling

This commit is contained in:
Sipke Schoorstra 2023-01-25 11:46:07 +01:00
parent 2697f512e9
commit fe845e65e7
6 changed files with 55 additions and 25 deletions

View file

@ -1,30 +1,53 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Elsa.Expressions.Models;
/// <summary>
/// Represents a literal JSON expression.
/// </summary>
public class JsonLiteral : MemoryBlockReference
{
/// <inheritdoc />
[JsonConstructor]
public JsonLiteral()
{
}
/// <inheritdoc />
public JsonLiteral(string? value)
{
Value = value;
}
/// <summary>
/// The literal JSON string value.
/// </summary>
public string? Value { get; }
/// <inheritdoc />
public override MemoryBlock Declare() => new();
/// <summary>
/// Serializes the value into a JSON string in the form of a <see cref="JsonLiteral{T}"/>
/// </summary>
/// <param name="value"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static JsonLiteral From<T>(T value) => new JsonLiteral<T>(value);
}
/// <summary>
/// Represents a JSON string for the specified type <code>T</code>
/// </summary>
public class JsonLiteral<T> : JsonLiteral
{
/// <inheritdoc />
public JsonLiteral()
{
}
/// <inheritdoc />
public JsonLiteral(T value) : base(JsonSerializer.Serialize(value!))
{
}

View file

@ -26,8 +26,8 @@ public class TypeDescriber : ITypeDescriber
{
DeclarationKeyword = GetDeclarationKeyword(type),
Name = type.Name,
Properties = GetPropertyDefinitions(type).ToList(),
Methods = GetMethodDefinitions(type).ToList()
Properties = GetPropertyDefinitions(type).DistinctBy(x => x.Name).ToList(),
Methods = GetMethodDefinitions(type).DistinctBy(x => x.Name).ToList()
};
return typeDefinition;

View file

@ -20,16 +20,21 @@ internal class VariableTypeDefinitionProvider : TypeDefinitionProvider
protected override IEnumerable<TypeDefinition> GetTypeDefinitions(TypeDefinitionContext context)
{
var excludedTypes = new[] { typeof(ExpandoObject), typeof(IDictionary<string, object>) };
var excludedTypes = new Func<Type, bool>[]
{
type => type == typeof(ExpandoObject),
type => typeof(IDictionary<string, object>).IsAssignableFrom(type),
type => type == typeof(object)
};
var variableTypeQuery =
from variable in context.Variables
let variableType = variable.GetVariableType()
where (variableType.IsClass || variableType.IsInterface) && !variableType.IsPrimitive && !excludedTypes.Any(x => x.IsAssignableFrom(variableType))
where (variableType.IsClass || variableType.IsInterface) && !variableType.IsPrimitive && !excludedTypes.Any(x => x(variableType))
select variableType;
var variableTypes = variableTypeQuery.Distinct();
foreach (var variableType in variableTypes)
{
yield return _typeDescriber.DescribeType(variableType);

View file

@ -6,8 +6,12 @@ using Elsa.Workflows.Core.Expressions;
namespace Elsa.Workflows.Core.Models;
/// <summary>
/// A base type for the <see cref="Input{T}"/> type.
/// </summary>
public abstract class Input : Argument
{
/// <inheritdoc />
protected Input(IExpression expression, MemoryBlockReference memoryBlockReference, Type type) : base(memoryBlockReference)
{
Expression = expression;
@ -19,60 +23,77 @@ public abstract class Input : Argument
[JsonPropertyName("typeName")] public Type Type { get; set; }
}
/// <summary>
/// Represents activity input that is evaluated at runtime.
/// </summary>
public class Input<T> : Input
{
/// <inheritdoc />
public Input(T literal, string? id = default) : this(new Literal<T>(literal) { Id = id! })
{
}
/// <inheritdoc />
public Input(Func<T> @delegate, string? id = default) : this(new DelegateBlockReference(() => @delegate()){ Id = id!})
{
}
/// <inheritdoc />
public Input(Func<ExpressionExecutionContext, ValueTask<T?>> @delegate) : this(new DelegateBlockReference<T>(@delegate))
{
}
/// <inheritdoc />
public Input(Func<ValueTask<T?>> @delegate) : this(new DelegateBlockReference<T>(@delegate))
{
}
/// <inheritdoc />
public Input(Func<ExpressionExecutionContext, T> @delegate) : this(new DelegateBlockReference<T>(@delegate))
{
}
/// <inheritdoc />
public Input(Variable variable) : base(new VariableExpression(variable), variable, typeof(T))
{
}
/// <inheritdoc />
public Input(Output output) : base(new OutputExpression(output), output.MemoryBlockReference(), typeof(T))
{
}
/// <inheritdoc />
public Input(Literal<T> literal) : base(new LiteralExpression(literal.Value), literal, typeof(T))
{
}
/// <inheritdoc />
public Input(Literal literal) : base(new LiteralExpression(literal.Value), literal, typeof(T))
{
}
/// <inheritdoc />
public Input(JsonLiteral<T> literal) : base(new JsonExpression(literal.Value), literal, typeof(T))
{
}
/// <inheritdoc />
public Input(JsonLiteral literal) : base(new JsonExpression(literal.Value), literal, typeof(T))
{
}
/// <inheritdoc />
public Input(DelegateBlockReference delegateBlockReference) : base(new DelegateExpression(delegateBlockReference), delegateBlockReference, typeof(T))
{
}
/// <inheritdoc />
public Input(ElsaExpression expression) : this(new ElsaExpressionBlockReference(expression))
{
}
/// <inheritdoc />
public Input(IExpression expression, MemoryBlockReference memoryBlockReference) : base(expression, memoryBlockReference, typeof(T))
{
}

View file

@ -1,19 +0,0 @@
using Elsa.Expressions.Models;
namespace Elsa.Workflows.Core.Models;
public class JsonObject : MemoryBlockReference
{
public JsonObject()
{
}
public JsonObject(string? defaultValue)
{
DefaultValue = defaultValue;
}
public string? Name { get; set; }
public string? DefaultValue { get; }
public override MemoryBlock Declare() => new(DefaultValue);
}

View file

@ -34,7 +34,7 @@ public class DefaultExpressionSyntaxProvider : IExpressionSyntaxProvider
private ExpressionSyntaxDescriptor CreateJsonDescriptor() => CreateDescriptor<JsonExpression>(
"Json",
CreateJsonExpression,
context => new JsonObject(context.GetExpression<JsonExpression>().Value),
context => new JsonLiteral(context.GetExpression<JsonExpression>().Value),
expression => expression.Value);
private ExpressionSyntaxDescriptor CreateDelegateDescriptor() => CreateDescriptor<DelegateExpression>(