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);
}
}
}