Skip to content

Instantly share code, notes, and snippets.

@adbre
Last active August 29, 2015 14:03
Show Gist options
  • Save adbre/52b1c5603c6f2fe89767 to your computer and use it in GitHub Desktop.
Save adbre/52b1c5603c6f2fe89767 to your computer and use it in GitHub Desktop.

Demonstrates what the type constraints are for the three common serializers plus the community popular serializer Newtonsoft JSON.NET.

Only JSON.NET solves all scenarios.

  • XmlSerializer

    • Normal type - YES
    • Internal type - No
    • Nested public - YES
    • Nested internal - No
    • Nested private - No
    • No default constructor - No
  • DataContractSerializer

    • Normal type - YES
    • Internal type - No
    • Nested public - YES
    • Nested internal - No
    • Nested private - No
    • No default constructor - No
  • DataContractJsonSerializer

    • Normal type - YES
    • Internal type - No
    • Nested public - YES
    • Nested internal - No
    • Nested private - No
    • No default constructor - No
  • Newtonsoft.Json

    • Normal type - YES
    • Internal type - YES
    • Nested public - YES
    • Nested internal - YES
    • Nested private - YES
    • No default constructor - YES
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Xml.Serialization;
using Newtonsoft.Json;
using NUnit.Framework;
namespace Lab
{
[TestFixture]
[TestFixture(typeof(NewtonsoftJsonSerializerWrapper))]
[TestFixture(typeof(XmlSerializerWrapper))]
[TestFixture(typeof(DataContractSerializerWrapper))]
[TestFixture(typeof(DataContractJsonSerializerWrapper))]
public class SerializationTypeRestraintTests<T> where T : ISerializer, new()
{
private readonly ISerializer _serializer;
public SerializationTypeRestraintTests()
{
_serializer = new T();
}
[Test]
public void ShouldSerializeNormalType()
{
ShouldSerialize(new NormalType());
}
[Test]
public void ShouldSerializeNestedPublicType()
{
ShouldSerialize(new NestedPublicType());
}
[Test]
public void ShouldSerializeNestedInternalType()
{
ShouldSerialize(new NestedInternalType());
}
[Test]
public void ShouldSerializeNestedPrivateType()
{
ShouldSerialize(new NestedPrivateType());
}
[Test]
public void ShouldSerializeNormalTypeWithoutDefaultConstructor()
{
ShouldSerialize(new NormalTypeWithoutDefaultConstructor(Guid.NewGuid()));
}
private void ShouldSerialize<TObj>(TObj obj) where TObj : ISerializationTarget
{
var expected = Guid.NewGuid();
obj.Value = expected;
var text = _serializer.Serialize(obj);
var actual = (ISerializationTarget)_serializer.Deserialize(typeof(TObj), text);
Assert.That(actual.Value, Is.EqualTo(expected));
}
public class NestedPublicType : ISerializationTarget
{
public Guid Value { get; set; }
}
internal class NestedInternalType : ISerializationTarget
{
public Guid Value { get; set; }
}
private class NestedPrivateType : ISerializationTarget
{
public Guid Value { get; set; }
}
}
public interface ISerializationTarget
{
Guid Value { get; set; }
}
public class NormalType : ISerializationTarget
{
public Guid Value { get; set; }
}
public class NormalTypeWithoutDefaultConstructor : ISerializationTarget
{
public NormalTypeWithoutDefaultConstructor(Guid value)
{
Value = value;
}
public Guid Value { get; set; }
}
public interface ISerializer
{
string Serialize(object obj);
object Deserialize(Type type, string text);
}
public class NewtonsoftJsonSerializerWrapper : ISerializer
{
public string Serialize(object obj)
{
return JsonConvert.SerializeObject(obj);
}
public object Deserialize(Type type, string text)
{
return JsonConvert.DeserializeObject(text, type);
}
}
public class XmlSerializerWrapper : ISerializer
{
public string Serialize(object obj)
{
var serializer = new XmlSerializer(obj.GetType());
using (var stringWriter = new StringWriter())
{
serializer.Serialize(stringWriter, obj);
return stringWriter.ToString();
}
}
public object Deserialize(Type type, string text)
{
var serializer = new XmlSerializer(type);
using (var stringReader = new StringReader(text))
return serializer.Deserialize(stringReader);
}
}
public abstract class XmlObjectSerializerWrapper : ISerializer
{
public string Serialize(object obj)
{
var serializer = CreateSerializer(obj.GetType());
using (var memoryStream = new MemoryStream())
{
serializer.WriteObject(memoryStream, obj);
memoryStream.Position = 0;
using (var streamReader = new StreamReader(memoryStream))
return streamReader.ReadToEnd();
}
}
public object Deserialize(Type type, string text)
{
var serializer = CreateSerializer(type);
using (var memoryStream = new MemoryStream())
using (var streamWriter = new StreamWriter(memoryStream))
{
streamWriter.Write(text);
streamWriter.Flush();
memoryStream.Position = 0;
return serializer.ReadObject(memoryStream);
}
}
protected abstract XmlObjectSerializer CreateSerializer(Type type);
}
public class DataContractSerializerWrapper : XmlObjectSerializerWrapper
{
protected override XmlObjectSerializer CreateSerializer(Type type)
{
return new DataContractSerializer(type);
}
}
public class DataContractJsonSerializerWrapper : XmlObjectSerializerWrapper
{
protected override XmlObjectSerializer CreateSerializer(Type type)
{
return new DataContractJsonSerializer(type);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment