Refactor Toon serializer: modularize metadata & relations

Major refactor: split AcToonSerializer.MetaSection.cs into focused modules for meta writing, type/enum definitions, navigation, foreign key, validation, descriptions, placeholders, topological sort, and attribute detection. Extend ToonDescriptionAttribute with BusinessRule, TypeRelation, and RelatedTypes for richer metadata. Add ToonTypeRelation constants. Annotate all DTOs with ToonDescription for type relationships. Refactor TypeMetadataBase for customizable ignore filters. Update tests and settings. Improves maintainability, extensibility, and metadata accuracy.
This commit is contained in:
Loretta 2026-01-14 15:39:03 +01:00
parent 0bb0b06af4
commit ca186c9e90
7 changed files with 20 additions and 7 deletions

View File

@ -1,10 +1,13 @@
using Mango.Nop.Core.Dtos;
using AyCode.Core.Serializers.Toons;
using Mango.Nop.Core.Dtos;
using Nop.Core.Domain.Common;
using Nop.Core.Domain.Orders;
namespace FruitBank.Common.Dtos;
[LinqToDB.Mapping.Table(Name = nameof(GenericAttribute))]
[System.ComponentModel.DataAnnotations.Schema.Table(nameof(GenericAttribute))]
[ToonDescription($"Data transfer object for {nameof(GenericAttribute)}", TypeRelation = ToonTypeRelation.DtoOf, RelatedTypes = [typeof(GenericAttribute)])]
public class GenericAttributeDto : MgGenericAttributeDto
{

View File

@ -1,4 +1,5 @@
using AyCode.Core.Extensions;
using AyCode.Core.Serializers.Toons;
using AyCode.Utils.Extensions;
using FruitBank.Common.Entities;
using FruitBank.Common.Enums;
@ -22,6 +23,7 @@ namespace FruitBank.Common.Dtos;
[LinqToDB.Mapping.Table(Name = nameof(Order))]
[System.ComponentModel.DataAnnotations.Schema.Table(nameof(Order))]
[ToonDescription($"Data transfer object for {nameof(Order)}", TypeRelation = ToonTypeRelation.DtoOf, RelatedTypes = [typeof(Order)])]
public class OrderDto : MgOrderDto<OrderItemDto, ProductDto>, IOrderDto
{
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]

View File

@ -1,4 +1,5 @@
using FruitBank.Common.Entities;
using AyCode.Core.Serializers.Toons;
using FruitBank.Common.Entities;
using FruitBank.Common.Enums;
using FruitBank.Common.Interfaces;
using LinqToDB.Mapping;
@ -16,6 +17,7 @@ namespace FruitBank.Common.Dtos;
[LinqToDB.Mapping.Table(Name = nameof(OrderItem))]
[System.ComponentModel.DataAnnotations.Schema.Table(nameof(OrderItem))]
[ToonDescription($"Data transfer object for {nameof(OrderItem)}", TypeRelation = ToonTypeRelation.DtoOf, RelatedTypes = [typeof(OrderItem)])]
public class OrderItemDto : MgOrderItemDto<ProductDto>, IOrderItemDto
{
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]

View File

@ -1,4 +1,5 @@
using FruitBank.Common.Interfaces;
using AyCode.Core.Serializers.Toons;
using FruitBank.Common.Interfaces;
using LinqToDB.Mapping;
using Mango.Nop.Core.Dtos;
using Mango.Nop.Core.Extensions;
@ -13,6 +14,7 @@ namespace FruitBank.Common.Dtos;
[LinqToDB.Mapping.Table(Name = "Product")]
[System.ComponentModel.DataAnnotations.Schema.Table("Product")]
[ToonDescription($"Data transfer object for Product")]
public class ProductDto : MgProductDto, IProductDto
{
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]

View File

@ -1,10 +1,12 @@
using FruitBank.Common.Interfaces;
using AyCode.Core.Serializers.Toons;
using FruitBank.Common.Interfaces;
using LinqToDB.Mapping;
using Mango.Nop.Core.Dtos;
using Mango.Nop.Core.Entities;
using Mango.Nop.Core.Interfaces;
using Newtonsoft.Json;
using Nop.Core.Domain.Catalog;
using Nop.Core.Domain.Common;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
@ -16,6 +18,7 @@ namespace FruitBank.Common.Dtos
{
[LinqToDB.Mapping.Table(Name = nameof(StockQuantityHistory))]
[System.ComponentModel.DataAnnotations.Schema.Table(nameof(StockQuantityHistory))]
[ToonDescription($"Data transfer object for {nameof(StockQuantityHistory)}", TypeRelation = ToonTypeRelation.DtoOf, RelatedTypes = [typeof(StockQuantityHistory)])]
public class StockQuantityHistoryDto : MgStockQuantityHistoryDto<ProductDto>, IStockQuantityHistoryDto
{
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]

View File

@ -39,8 +39,8 @@ public sealed class ToonTests
[TestMethod]
public void OrderDtoToToon()
{
var toon = AcToonSerializer.SerializeTypeMetadata<OrderDto>();
var orderDtos = _signalRClient.GetAllOrderDtos();
var toon = AcToonSerializer.Serialize(orderDtos, AcToonSerializerOptions.Default);
Console.WriteLine(toon);
Assert.IsNotEmpty(toon);
@ -106,7 +106,7 @@ public sealed class ToonTests
[TestMethod]
public void ToonTypes_NavigationMetadata_ShouldBeComplete()
{
var toon = AcToonSerializer.SerializeTypeMetadata<Shipping>();
var toon = AcToonSerializer.SerializeMetadata([typeof(Shipping), typeof(OrderDto)]);
Console.WriteLine(toon);
Console.WriteLine("\n=== NAVIGATION METADATA ELLENŐRZÉS ===\n");

1
tmpclaude-bf6e-cwd Normal file
View File

@ -0,0 +1 @@
/h/Applications/Mango/Source/FruitBankHybridApp