I have below interface:
public interface IInterface<out M>
{
M Message { get; }
string Str { get; }
}
And its implementation:
public class Implementation<M> : IInterface<M>
{
public M Message;
public string Str;
public Implementation(M message, string str)
{
Message = message;
Str = str;
}
M IInterface<M>.Message => this.Message;
string IInterface<M>.Str => this.Str;
}
Here is a sample M class:
public class Sample
{
public int X;
}
Here is the sample JSON I pass from javascript client:
{ "Message" : { "X": 100 }, "Str" : "abc" }
Now there is some legacy/external code (that I can't change) which tries to deserialize the above JSON object using Json.Net using DeserializeObject<IInterface<Sample>>(js_object_string)
.
How can I write a JsonConverter for this IInterface
interface that deals with its generic parameter M
. Most of the solutions on internet only work with the types that are known at compile time.
I tried below code (that I don't understand fully) but the external code doesn't think the deserialized object is IInterface
.
static class ReflectionHelper
{
public static IInterface<T> Get<T>()
{
var x = JsonConvert.DeserializeObject<T>(str);
IInterface<T> y = new Implementation<T>(x, "xyz");
return y;
}
}
class MyConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(IInterface<>));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var w = Newtonsoft.Json.Linq.JObject.Load(reader);
var x = typeof(ReflectionHelper).GetMethod(nameof(ReflectionHelper.Get)).MakeGenericMethod(objectType.GetGenericArguments()[0]).Invoke(null, new object[] { });
return x;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; // otherwise I get a circular dependency error.
serializer.Serialize(writer, value);
}
}