207 lines
6.4 KiB
C#
207 lines
6.4 KiB
C#
using e_suite.Database.Core.Models;
|
|
using e_suite.Database.Core.Tables.Contacts;
|
|
using e_suite.Database.Core.Tables.Domain;
|
|
using e_suite.Workflow.Core.Attributes;
|
|
using e_suite.Workflow.Core.Interfaces;
|
|
using eSuite.Core.Miscellaneous;
|
|
using System.Reflection;
|
|
using System.Text.Json;
|
|
using System.Text.Json.Serialization;
|
|
|
|
namespace e_suite.Workflow.Core.Extensions;
|
|
|
|
public static class TaskExtensions
|
|
{
|
|
private static Dictionary<string, object?> ToConfigDictionary(this ITask task)
|
|
{
|
|
var dictionary = new Dictionary<string, object?>();
|
|
|
|
var type = task.GetType();
|
|
var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
|
|
|
|
foreach (var prop in properties)
|
|
{
|
|
if (!prop.CanRead)
|
|
continue;
|
|
|
|
if (!prop.CanWrite)
|
|
continue;
|
|
|
|
var value = prop.GetValue(task);
|
|
|
|
dictionary[prop.Name] = value;
|
|
}
|
|
|
|
return dictionary;
|
|
}
|
|
|
|
public static ITask ToTask(this TaskDefinition definition, JsonSerializerOptions jsonSerializerOptions)
|
|
{
|
|
var type = Type.GetType(definition.Type);
|
|
|
|
if (type == null)
|
|
throw new InvalidOperationException($"Unknown task type '{definition.Type}'.");
|
|
|
|
var instance = Activator.CreateInstance(type) as ITask;
|
|
|
|
if (instance == null)
|
|
throw new InvalidOperationException($"Type '{definition.Type}' does not implement ITask.");
|
|
|
|
FromConfigDictionary(instance, definition.Config, jsonSerializerOptions);
|
|
|
|
return instance;
|
|
}
|
|
|
|
public static void FromConfigDictionary(this object obj, Dictionary<string, object?> dict, JsonSerializerOptions jsonSerializerOptions)
|
|
{
|
|
var type = obj.GetType();
|
|
|
|
foreach (var kvp in dict)
|
|
{
|
|
var prop = type.GetProperty(
|
|
kvp.Key,
|
|
BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase
|
|
);
|
|
|
|
if (prop == null || !prop.CanWrite)
|
|
continue;
|
|
|
|
var targetType = prop.PropertyType;
|
|
var value = kvp.Value;
|
|
|
|
// If the value is a JsonElement, convert it to the target type
|
|
if (value is JsonElement je)
|
|
{
|
|
if (targetType.IsEnum)
|
|
{
|
|
// Enums come through as strings
|
|
value = Enum.Parse(targetType, je.GetString()!, ignoreCase: true);
|
|
}
|
|
else
|
|
{
|
|
// Deserialize JSON into the target type (handles lists, objects, primitives)
|
|
value = JsonSerializer.Deserialize(je.GetRawText(), targetType, jsonSerializerOptions);
|
|
}
|
|
}
|
|
|
|
prop.SetValue(obj, value);
|
|
}
|
|
}
|
|
|
|
public static TaskDefinition ToDefinition(this ITask task)
|
|
{
|
|
if (task is null)
|
|
throw new NullReferenceException();
|
|
|
|
|
|
return new TaskDefinition
|
|
{
|
|
Type = task.GetType().FullName,
|
|
Config = task.ToConfigDictionary()
|
|
};
|
|
}
|
|
|
|
//public static TaskDefinition ToDefinition(this ITask task)
|
|
//{
|
|
// 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().FullName!,
|
|
// 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;
|
|
//}
|
|
} |