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:
parent
0bb0b06af4
commit
ca186c9e90
|
|
@ -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.Common;
|
||||||
|
using Nop.Core.Domain.Orders;
|
||||||
|
|
||||||
namespace FruitBank.Common.Dtos;
|
namespace FruitBank.Common.Dtos;
|
||||||
|
|
||||||
[LinqToDB.Mapping.Table(Name = nameof(GenericAttribute))]
|
[LinqToDB.Mapping.Table(Name = nameof(GenericAttribute))]
|
||||||
[System.ComponentModel.DataAnnotations.Schema.Table(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
|
public class GenericAttributeDto : MgGenericAttributeDto
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using AyCode.Core.Extensions;
|
using AyCode.Core.Extensions;
|
||||||
|
using AyCode.Core.Serializers.Toons;
|
||||||
using AyCode.Utils.Extensions;
|
using AyCode.Utils.Extensions;
|
||||||
using FruitBank.Common.Entities;
|
using FruitBank.Common.Entities;
|
||||||
using FruitBank.Common.Enums;
|
using FruitBank.Common.Enums;
|
||||||
|
|
@ -22,6 +23,7 @@ namespace FruitBank.Common.Dtos;
|
||||||
|
|
||||||
[LinqToDB.Mapping.Table(Name = nameof(Order))]
|
[LinqToDB.Mapping.Table(Name = nameof(Order))]
|
||||||
[System.ComponentModel.DataAnnotations.Schema.Table(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
|
public class OrderDto : MgOrderDto<OrderItemDto, ProductDto>, IOrderDto
|
||||||
{
|
{
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using FruitBank.Common.Entities;
|
using AyCode.Core.Serializers.Toons;
|
||||||
|
using FruitBank.Common.Entities;
|
||||||
using FruitBank.Common.Enums;
|
using FruitBank.Common.Enums;
|
||||||
using FruitBank.Common.Interfaces;
|
using FruitBank.Common.Interfaces;
|
||||||
using LinqToDB.Mapping;
|
using LinqToDB.Mapping;
|
||||||
|
|
@ -16,6 +17,7 @@ namespace FruitBank.Common.Dtos;
|
||||||
|
|
||||||
[LinqToDB.Mapping.Table(Name = nameof(OrderItem))]
|
[LinqToDB.Mapping.Table(Name = nameof(OrderItem))]
|
||||||
[System.ComponentModel.DataAnnotations.Schema.Table(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
|
public class OrderItemDto : MgOrderItemDto<ProductDto>, IOrderItemDto
|
||||||
{
|
{
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using FruitBank.Common.Interfaces;
|
using AyCode.Core.Serializers.Toons;
|
||||||
|
using FruitBank.Common.Interfaces;
|
||||||
using LinqToDB.Mapping;
|
using LinqToDB.Mapping;
|
||||||
using Mango.Nop.Core.Dtos;
|
using Mango.Nop.Core.Dtos;
|
||||||
using Mango.Nop.Core.Extensions;
|
using Mango.Nop.Core.Extensions;
|
||||||
|
|
@ -13,6 +14,7 @@ namespace FruitBank.Common.Dtos;
|
||||||
|
|
||||||
[LinqToDB.Mapping.Table(Name = "Product")]
|
[LinqToDB.Mapping.Table(Name = "Product")]
|
||||||
[System.ComponentModel.DataAnnotations.Schema.Table("Product")]
|
[System.ComponentModel.DataAnnotations.Schema.Table("Product")]
|
||||||
|
[ToonDescription($"Data transfer object for Product")]
|
||||||
public class ProductDto : MgProductDto, IProductDto
|
public class ProductDto : MgProductDto, IProductDto
|
||||||
{
|
{
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
using FruitBank.Common.Interfaces;
|
using AyCode.Core.Serializers.Toons;
|
||||||
|
using FruitBank.Common.Interfaces;
|
||||||
using LinqToDB.Mapping;
|
using LinqToDB.Mapping;
|
||||||
using Mango.Nop.Core.Dtos;
|
using Mango.Nop.Core.Dtos;
|
||||||
using Mango.Nop.Core.Entities;
|
using Mango.Nop.Core.Entities;
|
||||||
using Mango.Nop.Core.Interfaces;
|
using Mango.Nop.Core.Interfaces;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Nop.Core.Domain.Catalog;
|
using Nop.Core.Domain.Catalog;
|
||||||
|
using Nop.Core.Domain.Common;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
@ -16,6 +18,7 @@ namespace FruitBank.Common.Dtos
|
||||||
{
|
{
|
||||||
[LinqToDB.Mapping.Table(Name = nameof(StockQuantityHistory))]
|
[LinqToDB.Mapping.Table(Name = nameof(StockQuantityHistory))]
|
||||||
[System.ComponentModel.DataAnnotations.Schema.Table(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
|
public class StockQuantityHistoryDto : MgStockQuantityHistoryDto<ProductDto>, IStockQuantityHistoryDto
|
||||||
{
|
{
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,8 @@ public sealed class ToonTests
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void OrderDtoToToon()
|
public void OrderDtoToToon()
|
||||||
{
|
{
|
||||||
|
var orderDtos = _signalRClient.GetAllOrderDtos();
|
||||||
var toon = AcToonSerializer.SerializeTypeMetadata<OrderDto>();
|
var toon = AcToonSerializer.Serialize(orderDtos, AcToonSerializerOptions.Default);
|
||||||
|
|
||||||
Console.WriteLine(toon);
|
Console.WriteLine(toon);
|
||||||
Assert.IsNotEmpty(toon);
|
Assert.IsNotEmpty(toon);
|
||||||
|
|
@ -106,7 +106,7 @@ public sealed class ToonTests
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void ToonTypes_NavigationMetadata_ShouldBeComplete()
|
public void ToonTypes_NavigationMetadata_ShouldBeComplete()
|
||||||
{
|
{
|
||||||
var toon = AcToonSerializer.SerializeTypeMetadata<Shipping>();
|
var toon = AcToonSerializer.SerializeMetadata([typeof(Shipping), typeof(OrderDto)]);
|
||||||
Console.WriteLine(toon);
|
Console.WriteLine(toon);
|
||||||
Console.WriteLine("\n=== NAVIGATION METADATA ELLENŐRZÉS ===\n");
|
Console.WriteLine("\n=== NAVIGATION METADATA ELLENŐRZÉS ===\n");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
/h/Applications/Mango/Source/FruitBankHybridApp
|
||||||
Loading…
Reference in New Issue