| | | 1 | | using Elsa.Extensions; |
| | | 2 | | using Elsa.Workflows.Models; |
| | | 3 | | |
| | | 4 | | namespace Elsa.Workflows; |
| | | 5 | | |
| | | 6 | | public static class WorkflowExecutionResultExtensions |
| | | 7 | | { |
| | | 8 | | public static T GetActivityOutput<T>(this RunWorkflowResult result, IActivity activity, string? outputName = null) |
| | | 9 | | { |
| | 11 | 10 | | var value = result.WorkflowExecutionContext.GetOutputByActivityId(activity.Id, outputName); |
| | | 11 | | |
| | | 12 | | // If the value is already of the requested type, return it directly. |
| | 11 | 13 | | if (value is T tValue) |
| | 11 | 14 | | return tValue; |
| | | 15 | | |
| | | 16 | | // Handle nulls for reference/nullable types. |
| | 0 | 17 | | if (value is null) |
| | | 18 | | { |
| | | 19 | | // If T is a reference type or nullable, default(T) is fine. |
| | | 20 | | // Otherwise, this is a runtime error. |
| | 0 | 21 | | return default(T) is null ? default! : throw new InvalidCastException($"Cannot convert null to non-nullable |
| | | 22 | | } |
| | | 23 | | |
| | | 24 | | // Try to convert using System.Convert when possible (handles numeric casts like Double -> Int32). |
| | | 25 | | try |
| | | 26 | | { |
| | 0 | 27 | | var targetType = typeof(T); |
| | | 28 | | |
| | | 29 | | // Unwrap nullable<T> to its underlying type for conversion. |
| | 0 | 30 | | var underlyingType = Nullable.GetUnderlyingType(targetType) ?? targetType; |
| | | 31 | | |
| | 0 | 32 | | var converted = Convert.ChangeType(value, underlyingType, System.Globalization.CultureInfo.InvariantCulture) |
| | | 33 | | |
| | | 34 | | // If T is nullable and we converted to the underlying type, just cast. |
| | 0 | 35 | | return (T)converted!; |
| | | 36 | | } |
| | 0 | 37 | | catch (Exception ex) |
| | | 38 | | { |
| | 0 | 39 | | throw new InvalidCastException($"Unable to convert value of type '{value.GetType().FullName}' to type '{type |
| | | 40 | | } |
| | 0 | 41 | | } |
| | | 42 | | } |