using System; using System.Linq; using System.Reflection; using Newtonsoft.Json; namespace WorkerService.Process { /// /// Function JSON converter /// /// Function input type /// Function output type public class FunctionConverter : JsonConverter { /// /// Writes the JSON representation of the object /// /// The JsonWriter to write to /// The value to write /// The calling serializer public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { if (value is Func function) { writer.WriteValue($"{function.Method.DeclaringType}.{function.Method.Name}"); } } /// Reads the JSON representation of the object. /// JsonReader to read from /// Type of the object /// The existing value of object being read /// The calling serializer /// The object value public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { //Get the function's full path string fullFunctionPath = (string)reader.Value; if (string.IsNullOrEmpty(fullFunctionPath)) { return null; } //Extract class and function names string className = fullFunctionPath.Substring(0, fullFunctionPath.LastIndexOf(".", StringComparison.Ordinal)); string functionName = fullFunctionPath.Substring(fullFunctionPath.LastIndexOf(".", StringComparison.Ordinal) + 1); //Get the class type Type classType = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()).FirstOrDefault(t => string.Equals(t.FullName, className, StringComparison.CurrentCultureIgnoreCase)); if (classType == null) { return null; } //Get the function's method info MethodInfo methodInfo = classType.GetMethod(functionName); if (methodInfo == null) { return null; } return (Func)methodInfo.CreateDelegate(typeof(Func)); } /// /// Determines whether this instance can convert the specified object type /// /// Type of the object /// /// Whether or not this instance can convert ot the specified object type /// public override bool CanConvert(Type objectType) { return objectType == typeof(Func); } } }