122 lines
3.7 KiB
C#
122 lines
3.7 KiB
C#
using e_suite.Workflow.Core.Attributes;
|
|
using e_suite.Workflow.Core.Enums;
|
|
using e_suite.Workflow.Core.Interfaces;
|
|
using e_suite.Workflow.Core.Tasks;
|
|
|
|
namespace e_suite.Workflow.Core.Extensions;
|
|
|
|
//copied from Database.core.
|
|
public class TaskDefinition
|
|
{
|
|
public string Type { get; set; } = string.Empty;
|
|
public int Order { get; set; }
|
|
public Dictionary<string, object>? Config { get; set; }
|
|
}
|
|
|
|
public static class TaskExtensions
|
|
{
|
|
public static TaskDefinition ToDefinition(this ITask task, int order)
|
|
{
|
|
if (task is ITemplateValidatable v)
|
|
{
|
|
var errors = v.ValidateForTemplate().ToList();
|
|
if (errors.Count != 0)
|
|
throw new InvalidOperationException(
|
|
$"Task {task.GetType().Name} is invalid: {string.Join("; ", errors)}");
|
|
}
|
|
|
|
return new TaskDefinition
|
|
{
|
|
Type = task.GetType().AssemblyQualifiedName!,
|
|
Order = order,
|
|
Config = ExtractConfig(task)
|
|
};
|
|
}
|
|
|
|
private static Dictionary<string, object> ExtractConfig(object task)
|
|
{
|
|
var dict = new Dictionary<string, object>();
|
|
|
|
foreach (var prop in task.GetType().GetProperties())
|
|
{
|
|
if (!prop.CanRead) continue;
|
|
if (prop.GetIndexParameters().Length > 0) continue; // skip indexers
|
|
if (prop.IsDefined(typeof(RuntimeOnlyAttribute), inherit: true))
|
|
continue;
|
|
|
|
var value = prop.GetValue(task);
|
|
if (value != null)
|
|
dict[prop.Name] = value;
|
|
}
|
|
|
|
return dict;
|
|
}
|
|
|
|
public static ITask ToTask(this TaskDefinition def)
|
|
{
|
|
var type = Type.GetType(def.Type, throwOnError: true)!;
|
|
var task = (ITask)Activator.CreateInstance(type)!;
|
|
|
|
if (def.Config != null)
|
|
foreach (var kvp in def.Config)
|
|
{
|
|
var prop = type.GetProperty(kvp.Key);
|
|
if (prop == null || !prop.CanWrite) continue;
|
|
if (prop.IsDefined(typeof(RuntimeOnlyAttribute), inherit: true))
|
|
continue;
|
|
|
|
object? converted = ConvertValue(kvp.Value, prop.PropertyType);
|
|
prop.SetValue(task, converted);
|
|
}
|
|
|
|
if (task is ITemplateValidatable v)
|
|
{
|
|
var errors = v.ValidateForTemplate().ToList();
|
|
if (errors.Count != 0)
|
|
throw new InvalidOperationException(
|
|
$"Task {task.GetType().Name} is invalid: {string.Join("; ", errors)}");
|
|
}
|
|
|
|
return task;
|
|
}
|
|
|
|
private static object? ConvertValue(object? value, Type targetType)
|
|
{
|
|
if (value == null) return null;
|
|
|
|
// Handle enums
|
|
if (targetType.IsEnum)
|
|
return Enum.Parse(targetType, value.ToString()!);
|
|
|
|
// Handle Guid
|
|
if (targetType == typeof(Guid))
|
|
return Guid.Parse(value.ToString()!);
|
|
|
|
// Handle nullable types
|
|
var underlying = Nullable.GetUnderlyingType(targetType);
|
|
if (underlying != null)
|
|
return Convert.ChangeType(value, underlying);
|
|
|
|
return Convert.ChangeType(value, targetType);
|
|
}
|
|
|
|
|
|
//Todo can only be on a run-time instance
|
|
//public static bool IsCompleted(this ITask task)
|
|
//{
|
|
// return task.TaskState.In(TaskState.Completed, TaskState.Cancelled);
|
|
//}
|
|
|
|
//public static bool ReadyToActivate(this ITask task)
|
|
//{
|
|
// foreach (var predecessor in task.Predecessors)
|
|
// {
|
|
// if (!predecessor.IsCompleted())
|
|
// {
|
|
// return false;
|
|
// }
|
|
// }
|
|
|
|
// return true;
|
|
//}
|
|
} |