Skip to content

Commit

Permalink
Merge pull request #67 from manuc66/feature/support-for-multiple-disc…
Browse files Browse the repository at this point in the history
…riminators-on-single-type

Feature/support for multiple discriminators on single type
  • Loading branch information
manuc66 authored Apr 28, 2019
2 parents 3c31529 + 8867b14 commit 6ae4500
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 7 deletions.
53 changes: 49 additions & 4 deletions JsonSubTypes.Tests/DynamicRegisterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,27 @@ public void DeserializeIncompleteTest()

var result = JsonConvert.DeserializeObject<Animal>(json);


Assert.AreEqual(typeof(Cat), result.GetType());
Assert.AreEqual(0, result.Age);
Assert.AreEqual(7, (result as Cat)?.Lives);
}

[Test]
public void MultipleRegistrationNotAllowedWithSerializeDiscriminatorProperty()
{
var settings = new JsonSerializerSettings();
JsonConvert.DefaultSettings = () => settings;

var exception = Assert.Throws<InvalidOperationException>(() => JsonSubtypesConverterBuilder
.Of(typeof(Animal), "type")
.SerializeDiscriminatorProperty()
.RegisterSubtype(typeof(Shark), AnimalType.Shark)
.RegisterSubtype(typeof(Shark), AnimalType.HammerheadShark)
.Build());

Assert.AreEqual("Multiple discriminators on single type are not supported when discriminator serialization is enabled", exception.Message);
}

[Test]
public void SerializeTest()
{
Expand Down Expand Up @@ -142,7 +157,6 @@ public void UnregisteredTypeSerializeTest()
Assert.AreEqual(json, result);
}


[Test]
public void UnregisteredTypeSerializeTest2()
{
Expand Down Expand Up @@ -232,8 +246,38 @@ public class BinaryExpression : IExpression

public class ConstantExpression : IExpression
{
private string _type = "Constant";

public string Value { get; set; }
public string Type { get { return "Constant"; } }

public string Type
{
get => _type;
set => _type = value;
}
}

[Test]
public void MultipleRegistrationAllowed()
{
var settings = new JsonSerializerSettings();
JsonConvert.DefaultSettings = () => settings;

settings.Converters.Add(JsonSubtypesConverterBuilder
.Of(typeof(IExpression), "Type")
.RegisterSubtype(typeof(ConstantExpression), "Constant")
.RegisterSubtype(typeof(ConstantExpression), "StringConstant")
.Build());

var constant = JsonConvert.DeserializeObject<IExpression>("{\"Type\":\"Constant\",\"Value\":\"B\"}");
var stringConstant = JsonConvert.DeserializeObject<IExpression>("{\"Type\":\"StringConstant\",\"Value\":\"C\"}");

Assert.AreEqual(typeof(ConstantExpression), constant.GetType());
Assert.AreEqual(typeof(ConstantExpression), stringConstant.GetType());
Assert.AreEqual("Constant", constant.Type);
Assert.AreEqual("StringConstant", stringConstant.Type);
Assert.AreEqual("B", ((ConstantExpression)constant).Value);
Assert.AreEqual("C", ((ConstantExpression)stringConstant).Value);
}

[Test]
Expand Down Expand Up @@ -392,7 +436,8 @@ public void TestNestedObjectInBothWayParallel()
.Build());


Action test = () => {
Action test = () =>
{
var target = JsonConvert.SerializeObject(new BinaryExpression2
{
SubExpressionA = new ManyOrExpression2 { OrExpr = new List<IExpression2> { new ConstantExpression2 { Value = "A" }, new ConstantExpression2 { Value = "B" } } },
Expand Down
18 changes: 15 additions & 3 deletions JsonSubTypes/JsonSubtypesConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ internal class JsonSubtypesConverter : JsonSubtypes

[ThreadStatic] private static bool _isInsideWrite;
[ThreadStatic] private static bool _allowNextWrite;
private bool _addDiscriminatorFirst;
private readonly bool _addDiscriminatorFirst;

internal JsonSubtypesConverter(Type baseType, string discriminatorProperty,
Dictionary<object, Type> subTypeMapping, bool serializeDiscriminatorProperty, bool addDiscriminatorFirst) : base(discriminatorProperty)
Expand All @@ -47,7 +47,19 @@ internal JsonSubtypesConverter(Type baseType, string discriminatorProperty,
_addDiscriminatorFirst = addDiscriminatorFirst;
foreach (var type in _subTypeMapping)
{
_supportedTypes.Add(type.Value, type.Key);
if (_supportedTypes.ContainsKey(type.Value))
{
if (_serializeDiscriminatorProperty)
{
throw new InvalidOperationException(
"Multiple discriminators on single type are not supported " +
"when discriminator serialization is enabled");
}
}
else
{
_supportedTypes.Add(type.Value, type.Key);
}
}
}

Expand Down Expand Up @@ -109,4 +121,4 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s
jsonObj.WriteTo(writer);
}
}
}
}

0 comments on commit 6ae4500

Please sign in to comment.