/// <inheritdoc /> public bool Deserialize(IParser reader, Type expectedType, Func <IParser, Type, object> nestedObjectDeserializer, out object value) { if (!reader.Accept <MappingStart>(out var mapping)) { value = null; return(false); } var supportedTypes = typeDiscriminators.Where(t => t.BaseType == expectedType).ToList(); if (!supportedTypes.Any()) { if (original.Deserialize(reader, expectedType, nestedObjectDeserializer, out value)) { Validator.ValidateObject(value, new ValidationContext(value, null, null), true); return(true); } return(false); } var start = reader.Current.Start; Type actualType; ParsingEventBuffer buffer; try { buffer = new ParsingEventBuffer(ReadNestedMapping(reader)); actualType = CheckWithDiscriminators(expectedType, supportedTypes, buffer); } catch (Exception exception) { throw new YamlException(start, reader.Current.End, "Failed when resolving abstract type", exception); } buffer.Reset(); if (original.Deserialize(buffer, actualType, nestedObjectDeserializer, out value)) { Validator.ValidateObject(value, new ValidationContext(value, null, null), true); return(true); } return(false); }
/// <inheritdoc /> public bool TryResolve(ParsingEventBuffer buffer, out Type suggestedType) { if (buffer.TryFindMappingEntry( scalar => targetKey == scalar.Value, out Scalar key, out ParsingEvent value)) { if (value is Scalar valueScalar) { suggestedType = CheckName(valueScalar.Value); return(true); } FailEmpty(); } suggestedType = null; return(false); }
private static Type CheckWithDiscriminators(Type expectedType, IEnumerable <ITypeDiscriminator> supportedTypes, ParsingEventBuffer buffer) { foreach (var discriminator in supportedTypes) { buffer.Reset(); if (!discriminator.TryResolve(buffer, out var actualType)) { continue; } return(actualType); } throw new Exception( $"None of the registered type discriminators could supply a child class for {expectedType}"); }