AyCode.Core/AyCode.Core/Serializers/AcSerializerOptions.cs

88 lines
3.3 KiB
C#

using System.Reflection;
namespace AyCode.Core.Serializers;
public abstract class AcSerializerOptions
{
public abstract AcSerializerType SerializerType { get; init; }
/// <summary>
/// Reference handling mode for circular/shared references.
/// Default: OnlyId (JSON serializer requires All mode, OnlyId not yet implemented)
/// Note: Binary serializer supports OnlyId mode for IId-only tracking.
/// </summary>
public ReferenceHandlingMode ReferenceHandling { get; set; } = ReferenceHandlingMode.OnlyId;
/// <summary>
/// Maximum depth for serialization/deserialization.
/// 0 = root level only (primitives of root object)
/// 1 = root + first level of nested objects/collections
/// byte.MaxValue (255) = effectively unlimited
/// Default: byte.MaxValue
/// </summary>
public byte MaxDepth { get; init; } = byte.MaxValue;
/// <summary>
/// Throw exception on circular reference detection for non-IId types.
/// When true: Tracks all objects and throws InvalidOperationException on circular references.
/// When false: No tracking for non-IId types (faster, but circular refs may cause MaxDepth truncation).
/// Default: true (production safety)
/// Note: IId types are always tracked when ReferenceHandling != None.
/// </summary>
public bool ThrowOnCircularReference { get; init; } = true;
/// <summary>
/// Optional callback for custom property mapping during cross-type operations.
/// Used when deserializing/populating with Deserialize&lt;TSource, TDest&gt; or Populate&lt;TSource, TDest&gt;.
///
/// Use cases:
/// - Mapping between external DTOs and internal models (different class hierarchies)
/// - Handling property renames across versions
/// - Custom property pairing logic
///
/// If null (default), properties are matched by name.
/// Callback is invoked once during mapping build phase and result is cached.
///
/// Performance: ZERO overhead on same-type operations (Deserialize&lt;T&gt;).
/// </summary>
public PropertyMapperDelegate? PropertyMapper { get; init; }
}
public enum AcSerializerType : byte
{
Json = 0,
Binary = 1,
Toon = 2,
}
/// <summary>
/// Reference handling mode for serialization.
/// </summary>
public enum ReferenceHandlingMode : byte
{
/// <summary>
/// No reference handling - all objects serialized inline.
/// </summary>
None = 0,
/// <summary>
/// Reference handling only for IId objects - uses semantic Id for deduplication.
/// NOTE: Not fully implemented for JSON serializer - use All instead.
/// Binary serializer supports this mode.
/// </summary>
OnlyId = 1,
/// <summary>
/// Full reference handling for all objects.
/// </summary>
All = 2
}
/// <summary>
/// Delegate for custom property mapping during cross-type deserialization/population.
/// Enables mapping between different class hierarchies or renamed properties.
/// </summary>
/// <param name="sourceProperty">Property from the source type being deserialized</param>
/// <param name="destinationType">Target type being populated</param>
/// <returns>Mapped destination property, or null to skip this property</returns>
public delegate PropertyInfo? PropertyMapperDelegate(PropertyInfo sourceProperty, Type destinationType);