зеркало из https://github.com/stride3d/SharpYaml.git
Merge pull request #19 from roji/roundtrip_ctor
Can roundrip with type converter and no default ctor
This commit is contained in:
Коммит
995643d671
|
@ -13,15 +13,17 @@ namespace YamlDotNet.RepresentationModel.Serialization
|
|||
/// </summary>
|
||||
public class FullObjectGraphTraversalStrategy : IObjectGraphTraversalStrategy
|
||||
{
|
||||
protected readonly Serializer serializer;
|
||||
private readonly int maxRecursion;
|
||||
|
||||
public FullObjectGraphTraversalStrategy(int maxRecursion)
|
||||
public FullObjectGraphTraversalStrategy(Serializer serializer, int maxRecursion)
|
||||
{
|
||||
if(maxRecursion <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("maxRecursion", maxRecursion, "maxRecursion must be greater than 1");
|
||||
}
|
||||
|
||||
this.serializer = serializer;
|
||||
this.maxRecursion = maxRecursion;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace YamlDotNet.RepresentationModel.Serialization
|
||||
|
@ -22,16 +23,16 @@ namespace YamlDotNet.RepresentationModel.Serialization
|
|||
// base.TraverseObject(value, type, visitor);
|
||||
//}
|
||||
|
||||
public RoundtripObjectGraphTraversalStrategy(int maxRecursion)
|
||||
: base(maxRecursion)
|
||||
public RoundtripObjectGraphTraversalStrategy(Serializer serializer, int maxRecursion)
|
||||
: base(serializer, maxRecursion)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void SerializeProperties(object value, Type type, IObjectGraphVisitor visitor, int currentDepth)
|
||||
{
|
||||
if (!ReflectionUtility.HasDefaultConstructor(type))
|
||||
if (!ReflectionUtility.HasDefaultConstructor(type) && !serializer.Converters.Any(c => c.Accepts(type)))
|
||||
{
|
||||
throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Type '{0}' cannot be deserialized because it does not have a default constructor.", type));
|
||||
throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Type '{0}' cannot be deserialized because it does not have a default constructor or a type converter.", type));
|
||||
}
|
||||
|
||||
base.SerializeProperties(value, type, visitor, currentDepth);
|
||||
|
|
|
@ -71,14 +71,19 @@ namespace YamlDotNet.RepresentationModel.Serialization
|
|||
/// </summary>
|
||||
public sealed class Serializer
|
||||
{
|
||||
private readonly IList<IYamlTypeConverter> converters = new List<IYamlTypeConverter>();
|
||||
internal IList<IYamlTypeConverter> Converters { get; private set; }
|
||||
|
||||
public Serializer()
|
||||
{
|
||||
Converters = new List<IYamlTypeConverter>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a type converter to be used to serialize and deserialize specific types.
|
||||
/// </summary>
|
||||
public void RegisterTypeConverter(IYamlTypeConverter converter)
|
||||
{
|
||||
converters.Add(converter);
|
||||
Converters.Add(converter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -155,7 +160,7 @@ namespace YamlDotNet.RepresentationModel.Serialization
|
|||
{
|
||||
IObjectGraphVisitor emittingVisitor = new EmittingObjectGraphVisitor(eventEmitter);
|
||||
|
||||
emittingVisitor = new CustomSerializationObjectGraphVisitor(emitter, emittingVisitor, converters);
|
||||
emittingVisitor = new CustomSerializationObjectGraphVisitor(emitter, emittingVisitor, Converters);
|
||||
|
||||
if ((options & SerializationOptions.DisableAliases) == 0)
|
||||
{
|
||||
|
@ -191,11 +196,11 @@ namespace YamlDotNet.RepresentationModel.Serialization
|
|||
{
|
||||
if ((options & SerializationOptions.Roundtrip) != 0)
|
||||
{
|
||||
return new RoundtripObjectGraphTraversalStrategy(50);
|
||||
return new RoundtripObjectGraphTraversalStrategy(this, 50);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new FullObjectGraphTraversalStrategy(50);
|
||||
return new FullObjectGraphTraversalStrategy(this, 50);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ using System;
|
|||
using System.Drawing;
|
||||
using Xunit;
|
||||
using System.IO;
|
||||
using YamlDotNet.Core;
|
||||
using YamlDotNet.RepresentationModel.Serialization;
|
||||
using System.Reflection;
|
||||
using System.Collections;
|
||||
|
@ -554,15 +555,47 @@ namespace YamlDotNet.UnitTests.RepresentationModel
|
|||
#endregion
|
||||
}
|
||||
|
||||
//[Fact]
|
||||
//public void DeserializeTypeConverter()
|
||||
//{
|
||||
// YamlSerializer<Z> serializer = new YamlSerializer<Z>();
|
||||
// object result = serializer.Deserialize(YamlFile("converter.yaml"));
|
||||
class SomeCustomeType
|
||||
{
|
||||
// Test specifically with no parameterless, supposed to fail unless a type converter is specified
|
||||
public SomeCustomeType(string value) { Value = value; }
|
||||
public string Value;
|
||||
}
|
||||
|
||||
// Assert.True(typeof(Z).IsAssignableFrom(result.GetType()));
|
||||
// Assert.Equal("[hello, world]", ((Z)result).aaa, "The property has the wrong value.");
|
||||
//}
|
||||
public class CustomTypeConverter : IYamlTypeConverter
|
||||
{
|
||||
public bool Accepts(Type type) { return type == typeof(SomeCustomeType); }
|
||||
|
||||
public object ReadYaml(Parser parser, Type type)
|
||||
{
|
||||
var value = ((Scalar)parser.Current).Value;
|
||||
parser.MoveNext();
|
||||
return new SomeCustomeType(value);
|
||||
}
|
||||
|
||||
public void WriteYaml(Emitter emitter, object value, Type type)
|
||||
{
|
||||
emitter.Emit(new Scalar(((SomeCustomeType)value).Value));
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RoundtripWithTypeConverter()
|
||||
{
|
||||
SomeCustomeType x = new SomeCustomeType("Yo");
|
||||
var serializer = new Serializer();
|
||||
serializer.RegisterTypeConverter(new CustomTypeConverter());
|
||||
StringWriter buffer = new StringWriter();
|
||||
serializer.Serialize(buffer, x, SerializationOptions.Roundtrip);
|
||||
|
||||
Console.WriteLine(buffer.ToString());
|
||||
|
||||
var deserializer = new YamlSerializer<SomeCustomeType>(YamlSerializerModes.Roundtrip);
|
||||
deserializer.RegisterTypeConverter(new CustomTypeConverter());
|
||||
|
||||
var copy = deserializer.Deserialize(new StringReader(buffer.ToString()));
|
||||
Assert.Equal("Yo", copy.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RoundtripDictionary()
|
||||
|
|
Загрузка…
Ссылка в новой задаче