Last active
August 29, 2015 14:16
-
-
Save hediet/3db87d8f39c22ffee9de to your computer and use it in GitHub Desktop.
CustomDiscriminatorObjectConverter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Diagnostics.Contracts; | |
using System.Linq; | |
using Newtonsoft.Json; | |
using Newtonsoft.Json.Linq; | |
namespace Hediet.Json.Converter | |
{ | |
public class CustomDiscriminatorObjectConverter : Newtonsoft.Json.JsonConverter | |
{ | |
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) | |
{ | |
throw new NotSupportedException(); | |
} | |
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) | |
{ | |
var discrimatorKey = GetDiscriminatorKey(objectType); | |
var obj = JObject.Load(reader); | |
var discriminator = obj[discrimatorKey].Value<string>(); | |
obj.Remove(discrimatorKey); | |
var type = ResolveDiscriminator(objectType, discriminator); | |
return serializer.Deserialize(obj.CreateReader(), type); | |
} | |
protected virtual Type ResolveDiscriminator(Type type, string discriminator) | |
{ | |
var attrs = type.GetCustomAttributes(typeof(DiscriminatedSubtypeAttribute), false).OfType<DiscriminatedSubtypeAttribute>(); | |
var attr = attrs.FirstOrDefault(a => a.Discriminator == discriminator); | |
if (attr == null) | |
return null; | |
return attr.Type; | |
} | |
protected virtual string GetDiscriminatorKey(Type type) | |
{ | |
var attr = type.GetCustomAttributes(typeof (DiscriminatedClassAttribute), false).OfType<DiscriminatedClassAttribute>().FirstOrDefault(); | |
if (attr == null) | |
return null; | |
return attr.DiscriminatorKey; | |
} | |
public override bool CanConvert(Type objectType) | |
{ | |
if (!objectType.IsClass && !objectType.IsInterface) | |
return false; | |
var d = GetDiscriminatorKey(objectType); | |
return d != null; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
namespace Hediet.Json.Converter | |
{ | |
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)] | |
public sealed class DiscriminatedClassAttribute : Attribute | |
{ | |
public string DiscriminatorKey { get; private set; } | |
public DiscriminatedClassAttribute(string discriminatorKey) | |
{ | |
DiscriminatorKey = discriminatorKey; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
namespace Hediet.Json.Converter | |
{ | |
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)] | |
public sealed class DiscriminatedSubtypeAttribute : Attribute | |
{ | |
public string Discriminator { get; private set; } | |
public Type Type { get; private set; } | |
public DiscriminatedSubtypeAttribute(string discriminator, Type type) | |
{ | |
Discriminator = discriminator; | |
Type = type; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment