using System; using System.Text.Json; using System.Text.Json.Serialization; public class Libro { public enum Tipo { TapaBlanda, TapaDura, Bolsillo } public /*required*/ Autor Autor { get; init; } public /*required*/ string Titulo { get; init; } public /*required*/ int Pags { get; init; } public /*required*/ string Isbn { get; init; } public /*required*/ Tipo Formato { get; init; } public override string ToString() { return $"{Autor.Nombre}: {Titulo} (ISBN: {Isbn}, {Pags} pgs.)"; } } public class Autor { public Autor() { this.libros = new List(); } public /*required*/ string Nombre { get; init; } public /*required*/ int AnnoNac { get; init; } public Autor Inserta(Libro libro) { this.libros.Add( libro ); return this; } public IList Libros { get => ( (List) this.libros ).AsReadOnly(); init { this.libros.Clear(); foreach (var libro in value) { this.libros.Add( libro ); } } } public override string ToString() { string infoAutor = $"{this.Nombre} ({this.AnnoNac})"; return infoAutor + "\n" + string.Join( '\n', this.Libros); } private IList libros; } public class Biblioteca { public Biblioteca() { this.autores = new List(); } public /*required*/ string Nombre { get; init; } public IList Autores { get => ( (List) this.autores ).AsReadOnly(); init { this.autores.Clear(); foreach (var autor in value) { this.autores.Add( autor ); } } } public Biblioteca Inserta(Autor autor) { this.autores.Add( autor ); return this; } public override string ToString() { return this.Nombre + "\n" + string.Join( '\n', this.Autores ); } private IList autores; } public class JsonBiblioteca { public /*required*/ Biblioteca Biblioteca { get; init; } public void Save(string nf) { using var f = new FileStream( nf, FileMode.Create ); var opts = new JsonSerializerOptions { ReferenceHandler = ReferenceHandler.Preserve }; JsonSerializer.Serialize( f, this.Biblioteca, opts ); } public static Biblioteca? Load(string nf) { using var f = new FileStream( nf, FileMode.Open ); var opts = new JsonSerializerOptions { ReferenceHandler = ReferenceHandler.Preserve }; //opts.Converters.Add( new BibliotecaJsonConverter() ); //opts.Converters.Add( new AutorJsonConverter() ); return JsonSerializer.Deserialize( f, opts ); } } public class BibliotecaJsonConverter: JsonConverter { public override Biblioteca? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { Biblioteca? toret = null; string nombre = ""; ICollection? autores = new List(); reader.Read(); if ( reader.TokenType == JsonTokenType.PropertyName && reader.ValueTextEquals( "Nombre" ) ) { reader.Read(); nombre = reader.GetString() ?? ""; reader.Read(); autores = JsonSerializer.Deserialize>(ref reader, options); toret = new Biblioteca { Nombre = nombre }; foreach (var autor in autores ?? new List()) { toret.Inserta( autor ); } reader.Read(); // endobject reader.Read(); } return toret; } public override void Write(Utf8JsonWriter writer, Biblioteca value, JsonSerializerOptions options) { throw new NotImplementedException(); } } public class AutorJsonConverter: JsonConverter { public override Autor? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { Autor? toret = null; string nombre = ""; int annonac = 1451; // se inventa la imprenta ICollection? libros = new List(); reader.Read(); while ( reader.TokenType != JsonTokenType.EndObject ) { if ( reader.TokenType == JsonTokenType.PropertyName && reader.ValueTextEquals( "Nombre" ) ) { reader.Read(); nombre = reader.GetString() ?? ""; } else if ( reader.TokenType == JsonTokenType.PropertyName && reader.ValueTextEquals( "AnnoNac" ) ) { reader.Read(); annonac = reader.GetInt32(); } else if ( reader.TokenType == JsonTokenType.PropertyName && reader.ValueTextEquals( "Libros" ) ) { libros = JsonSerializer.Deserialize>(ref reader, options); toret = new Autor { Nombre = nombre, AnnoNac = annonac }; foreach (var libro in libros ?? new List()) { toret.Inserta( libro ); } } reader.Read(); } return toret; } public override void Write(Utf8JsonWriter writer, Autor value, JsonSerializerOptions options) { throw new NotImplementedException(); } } class Test { static void Main() { var biblio = new Biblioteca { Nombre = "Universitaria UVigo" }; var julio = new Autor { Nombre = "Julio Verne", AnnoNac = 1828 }; var alex = new Autor { Nombre = "Alejandro Dumas", AnnoNac = 1802 }; biblio.Inserta( julio ) .Inserta( alex ); var libro1 = new Libro { Titulo = "Viaje al centro de la tierra", Autor = julio, Formato = Libro.Tipo.Bolsillo, Isbn = "978-8468253572", Pags = 330 }; var libro2 = new Libro { Titulo = "Los tres mosqueteros", Autor = alex, Formato = Libro.Tipo.TapaBlanda, Isbn = "978-8491052401", Pags = 617 }; var libro3 = new Libro { Titulo = "La vuelta al mundo en ochenta días", Autor = julio, Formato = Libro.Tipo.TapaDura, Isbn = "978-8431662950", Pags = 384 }; julio.Inserta( libro1 ) .Inserta( libro3 ); alex.Inserta( libro2 ); Console.WriteLine( biblio ); new JsonBiblioteca{ Biblioteca = biblio }.Save( "biblio.json" ); Console.WriteLine( "Lectura:" ); var biblio2 = JsonBiblioteca.Load( "biblio.json" ); Console.WriteLine( biblio2 ); } }