Using YamlDotNet , I am trying to deserialize the following YAML:
Collection: - Type: TypeA TypeAProperty: value1 - Type: TypeB TypeBProperty: value2
The Type property is required for all objects in the Collection . Other properties depend on the type.
This is my ideal object model:
public class Document { public IEnumerable<IBaseObject> Collection { get; set; } } public interface IBaseObject { public string Type { get; } } public class TypeAClass : IBaseObject { public string Type { get; set; } public string TypeAProperty { get; set; } } public class TypeBClass : IBaseObject { public string Type { get; set; } public string TypeBProperty { get; set; } }
Based on my reading, I find it best to use a special node deserializer derived from INodeDeserializer . As a proof of concept, I can do this:
public class MyDeserializer : INodeDeserializer { public bool Deserialize(IParser parser, Type expectedType, Func<IParser, Type, object> nestedObjectDeserializer, out object value) { if (expectedType == typeof(IBaseObject)) { Type type = typeof(TypeAClass); value = nestedObjectDeserializer(parser, type); return true; } value = null; return false; } }
Now my problem is how to dynamically determine the Type to select before calling nestedObjectDeserializer .
When using JSON.Net, I was able to use CustomCreationConverter , read sub-JSON in JObject , determine my type, then create a new JsonReader from JObject and re-parse the object.
Is there a way to read, roll back, and then re-read nestedObjectDeserializer ?
Is there any other type of object that I can call on nestedObjectDeserializer , and then from it reading the Type property, finally do the usual analysis of the derived YllDotNet kernel expression type?