You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

PolymorphicJSONConverter.cs 2.2 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. using LLama.Abstractions;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Reflection;
  6. using System.Text;
  7. using System.Text.Json;
  8. using System.Text.Json.Serialization;
  9. namespace LLama.Common
  10. {
  11. internal class PolymorphicJSONConverter<T> : JsonConverter<T>
  12. {
  13. public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
  14. {
  15. if (reader.TokenType != JsonTokenType.StartObject)
  16. throw new JsonException();
  17. reader.Read();
  18. if (reader.TokenType != JsonTokenType.PropertyName)
  19. throw new JsonException();
  20. string? propertyName = reader.GetString();
  21. if (propertyName != "Name")
  22. return default;
  23. reader.Read();
  24. if (reader.TokenType != JsonTokenType.String)
  25. throw new JsonException();
  26. string? name = reader.GetString() ?? throw new JsonException();
  27. var inheritedTypes = Assembly.GetExecutingAssembly().GetTypes().Where(
  28. t => typeof(T).IsAssignableFrom(t) && !t.IsAbstract && !t.IsInterface
  29. );
  30. var type = inheritedTypes.FirstOrDefault(t => t.Name == name);
  31. if (type == null)
  32. throw new JsonException();
  33. reader.Read();
  34. if (reader.TokenType != JsonTokenType.PropertyName)
  35. throw new JsonException();
  36. propertyName = reader.GetString();
  37. if (propertyName != "Data")
  38. throw new JsonException();
  39. var data = JsonSerializer.Deserialize(ref reader, type, options);
  40. if (data == null)
  41. throw new JsonException();
  42. reader.Read();
  43. reader.Read();
  44. return (T)data;
  45. }
  46. public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
  47. {
  48. writer.WriteStartObject();
  49. writer.WriteString("Name", value.GetType().Name);
  50. writer.WritePropertyName("Data");
  51. JsonSerializer.Serialize(writer, value, value.GetType(), options);
  52. writer.WriteEndObject();
  53. }
  54. }
  55. }