diff --git a/AyCode.Core/Serializers/AcSerializerContextBase.cs b/AyCode.Core/Serializers/AcSerializerContextBase.cs
index 7117dee..e60fddc 100644
--- a/AyCode.Core/Serializers/AcSerializerContextBase.cs
+++ b/AyCode.Core/Serializers/AcSerializerContextBase.cs
@@ -13,8 +13,16 @@ namespace AyCode.Core.Serializers;
/// GlobalMetadataCache stores metadata (thread-safe), wrappers store per-context tracking.
///
/// The concrete metadata type.
-public abstract class AcSerializerContextBase where TMetadata : TypeMetadataBase
+/// The concrete options type.
+public abstract class AcSerializerContextBase
+ where TMetadata : TypeMetadataBase
+ where TOptions : AcSerializerOptions
{
+ ///
+ /// The options used for this context. Set during Reset.
+ ///
+ public TOptions Options { get; private set; } = null!;
+
public byte MaxDepth { get; private set; }
public ReferenceHandlingMode ReferenceHandling { get; internal set; }
///
@@ -33,6 +41,19 @@ public abstract class AcSerializerContextBase where TMetadata : TypeM
///
protected abstract Func MetadataFactory { get; }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public bool UseTypeReferenceHandling(Type type)
+ {
+ var wrapper = GetWrapper(type);
+ return UseTypeReferenceHandling(wrapper.Metadata);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public bool UseTypeReferenceHandling(TMetadata metaData)
+ {
+ return ReferenceHandling != ReferenceHandlingMode.None && (metaData.IsIId || ReferenceHandling == ReferenceHandlingMode.All);
+ }
+
#region Wrapper Access
///
@@ -119,15 +140,14 @@ public abstract class AcSerializerContextBase where TMetadata : TypeM
/// Resets all wrapper tracking states for reuse.
/// Does not remove wrappers - keeps them for next operation.
///
- public virtual void Reset(in AcSerializerOptions? options)
+ public virtual void Reset(TOptions options)
{
foreach (var wrapper in _wrappers.Values)
{
wrapper.ResetTracking();
}
- if (options == null) return;
-
+ Options = options;
MaxDepth = options.MaxDepth;
ReferenceHandling = options.ReferenceHandling;
}
diff --git a/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.BinaryDeserializationContextClass.cs b/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.BinaryDeserializationContextClass.cs
index 0798333..acf654d 100644
--- a/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.BinaryDeserializationContextClass.cs
+++ b/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.BinaryDeserializationContextClass.cs
@@ -11,7 +11,7 @@ public static partial class AcBinaryDeserializer
/// Inherits from AcSerializerContextBase for unified metadata caching and IId-based reference tracking.
/// Used in composition with the ref struct BinaryDeserializationContext.
///
- internal sealed class BinaryDeserializationContextClass : AcSerializerContextBase
+ internal sealed class BinaryDeserializationContextClass : AcSerializerContextBase
{
///
/// Factory for creating BinaryDeserializeTypeMetadata instances.
@@ -19,6 +19,12 @@ public static partial class AcBinaryDeserializer
protected override Func MetadataFactory
=> static t => new BinaryDeserializeTypeMetadata(t);
+ public BinaryDeserializationContextClass()
+ {
+ // Initialize with default options - will be reset with actual options before use
+ Reset(AcBinarySerializerOptions.Default);
+ }
+
///
/// After PopulateObject, checks if we should reuse an existing IId object.
/// Uses the unified tracking from AcSerializerContextBase (IdentityMap).
diff --git a/AyCode.Core/Serializers/Binaries/AcBinarySerializer.BinarySerializationContext.cs b/AyCode.Core/Serializers/Binaries/AcBinarySerializer.BinarySerializationContext.cs
index 04e34f3..5171450 100644
--- a/AyCode.Core/Serializers/Binaries/AcBinarySerializer.BinarySerializationContext.cs
+++ b/AyCode.Core/Serializers/Binaries/AcBinarySerializer.BinarySerializationContext.cs
@@ -49,7 +49,7 @@ public static partial class AcBinarySerializer
///
/// Binary serialization context. Public for generated serializers.
///
- internal sealed class BinarySerializationContext : SerializationContextBase, IDisposable
+ internal sealed class BinarySerializationContext : SerializationContextBase, IDisposable
{
private const int MinBufferSize = 256;
private const int PropertyIndexBufferMaxCache = 512;
@@ -72,11 +72,12 @@ public static partial class AcBinarySerializer
private int[]? _propertyIndexBuffer;
private byte[]? _propertyStateBuffer;
- public bool UseStringInterning { get; private set; }
- public bool UseMetadata { get; private set; }
- public byte MinStringInternLength { get; private set; }
- public byte MaxStringInternLength { get; private set; }
- public BinaryPropertyFilter? PropertyFilter { get; private set; }
+ // These properties delegate to Options for convenience
+ public bool UseStringInterning => Options.UseStringInterning;
+ public bool UseMetadata => Options.UseMetadata;
+ public byte MinStringInternLength => Options.MinStringInternLength;
+ public byte MaxStringInternLength => Options.MaxStringInternLength;
+ public BinaryPropertyFilter? PropertyFilter => Options.PropertyFilter;
public int Position => _position;
@@ -93,17 +94,12 @@ public static partial class AcBinarySerializer
protected override Func MetadataFactory
=> static t => new BinarySerializeTypeMetadata(t, HasJsonIgnoreAttribute);
- public void Reset(AcBinarySerializerOptions options)
+ public override void Reset(AcBinarySerializerOptions options)
{
// Reset wrapper tracking state from base class (IId tracking)
base.Reset(options);
_position = 0;
- UseStringInterning = options.UseStringInterning;
- UseMetadata = options.UseMetadata;
- MinStringInternLength = options.MinStringInternLength;
- MaxStringInternLength = options.MaxStringInternLength;
- PropertyFilter = options.PropertyFilter;
_initialBufferSize = Math.Max(options.InitialBufferCapacity, MinBufferSize);
if (_buffer.Length < _initialBufferSize)
diff --git a/AyCode.Core/Serializers/DeserializationContextBase.cs b/AyCode.Core/Serializers/DeserializationContextBase.cs
index 4f37ceb..67b3440 100644
--- a/AyCode.Core/Serializers/DeserializationContextBase.cs
+++ b/AyCode.Core/Serializers/DeserializationContextBase.cs
@@ -9,8 +9,10 @@ namespace AyCode.Core.Serializers;
/// Derived classes are sealed for JIT devirtualization (direct call speed).
///
/// The concrete metadata type for deserialization.
-public abstract class DeserializationContextBase : AcSerializerContextBase
+/// The concrete options type.
+public abstract class DeserializationContextBase : AcSerializerContextBase
where TMetadata : TypeMetadataBase
+ where TOptions : AcSerializerOptions
{
#region Object Lookup by Id (to be implemented by derived sealed classes)
@@ -41,7 +43,7 @@ public abstract class DeserializationContextBase : AcSerializerContex
///
/// Resets deserialization-specific state. Called by derived classes.
///
- public override void Reset(in AcSerializerOptions options)
+ public override void Reset(TOptions options)
{
base.Reset(options);
// Future: Reset deserialization-specific state
diff --git a/AyCode.Core/Serializers/Jsons/AcJsonDeserializer.JsonDeserializationContext.cs b/AyCode.Core/Serializers/Jsons/AcJsonDeserializer.JsonDeserializationContext.cs
index 3c38f6c..b15339e 100644
--- a/AyCode.Core/Serializers/Jsons/AcJsonDeserializer.JsonDeserializationContext.cs
+++ b/AyCode.Core/Serializers/Jsons/AcJsonDeserializer.JsonDeserializationContext.cs
@@ -22,11 +22,11 @@ public static partial class AcJsonDeserializer
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void Return(DeserializationContext context, in AcSerializerOptions options)
+ public static void Return(DeserializationContext context, in AcJsonSerializerOptions options)
{
if (Pool.Count < MaxPoolSize)
{
- context.Clear(null);
+ context.Clear(options);
Pool.Enqueue(context);
}
}
@@ -45,7 +45,7 @@ public static partial class AcJsonDeserializer
public readonly int RefId = refId;
}
- private sealed class DeserializationContext : AcSerializerContextBase
+ private sealed class DeserializationContext : AcSerializerContextBase
{
// Use shared reference tracker from AcSerializerCommon
private readonly AcSerializerCommon.DeserializationReferenceTracker _refTracker = new();
@@ -75,7 +75,7 @@ public static partial class AcJsonDeserializer
Reset(options);
}
- public override void Reset(in AcSerializerOptions? options)
+ public override void Reset(AcJsonSerializerOptions options)
{
IsMergeMode = false;
ChainTracker = null;
@@ -84,7 +84,7 @@ public static partial class AcJsonDeserializer
base.Reset(options);
}
- public void Clear(in AcSerializerOptions? options)
+ public void Clear(AcJsonSerializerOptions options)
{
_refTracker.Reset();
_propertiesToResolve?.Clear();
diff --git a/AyCode.Core/Serializers/Jsons/AcJsonSerializer.JsonSerializationContext.cs b/AyCode.Core/Serializers/Jsons/AcJsonSerializer.JsonSerializationContext.cs
index 3f2bbfb..3374d60 100644
--- a/AyCode.Core/Serializers/Jsons/AcJsonSerializer.JsonSerializationContext.cs
+++ b/AyCode.Core/Serializers/Jsons/AcJsonSerializer.JsonSerializationContext.cs
@@ -35,7 +35,7 @@ public static partial class AcJsonSerializer
}
}
- private sealed class JsonSerializationContext : SerializationContextBase, IDisposable
+ private sealed class JsonSerializationContext : SerializationContextBase, IDisposable
{
private readonly ArrayBufferWriter _buffer;
public Utf8JsonWriter Writer { get; private set; }
@@ -62,11 +62,11 @@ public static partial class AcJsonSerializer
protected override Func MetadataFactory
=> static t => new JsonSerializeTypeMetadata(t);
- public override void Reset(in AcSerializerOptions options)
+ public override void Reset(AcJsonSerializerOptions options)
{
_refTracker.Reset();
- if (ReferenceHandling != ReferenceHandlingMode.None)
+ if (options.ReferenceHandling != ReferenceHandlingMode.None)
{
_refTracker.EnsureInitialized();
}
diff --git a/AyCode.Core/Serializers/SerializationContextBase.cs b/AyCode.Core/Serializers/SerializationContextBase.cs
index e7d2d7b..21d08a5 100644
--- a/AyCode.Core/Serializers/SerializationContextBase.cs
+++ b/AyCode.Core/Serializers/SerializationContextBase.cs
@@ -11,8 +11,10 @@ namespace AyCode.Core.Serializers;
/// Derived classes are sealed for JIT devirtualization (direct call speed).
///
/// The concrete metadata type for serialization.
-public abstract class SerializationContextBase : AcSerializerContextBase
+/// The concrete options type.
+public abstract class SerializationContextBase : AcSerializerContextBase
where TMetadata : TypeMetadataBase
+ where TOptions : AcSerializerOptions
{
private const int BitArraySize = 1024;
private const int MaxSmallId = BitArraySize * 64;
@@ -103,7 +105,7 @@ public abstract class SerializationContextBase : AcSerializerContextB
///
/// Resets serialization-specific state. Called by derived classes.
///
- public override void Reset(in AcSerializerOptions options)
+ public override void Reset(TOptions options)
{
base.Reset(options);
// Future: Reset serialization-specific state
diff --git a/AyCode.Core/Serializers/Toons/AcToonSerializer.ToonSerializationContext.cs b/AyCode.Core/Serializers/Toons/AcToonSerializer.ToonSerializationContext.cs
index 00c23cc..9636dff 100644
--- a/AyCode.Core/Serializers/Toons/AcToonSerializer.ToonSerializationContext.cs
+++ b/AyCode.Core/Serializers/Toons/AcToonSerializer.ToonSerializationContext.cs
@@ -49,7 +49,7 @@ public static partial class AcToonSerializer
/// Pooled context for Toon serialization.
/// Handles output building, indentation, and reference tracking.
///
- private sealed class ToonSerializationContext : SerializationContextBase
+ private sealed class ToonSerializationContext : SerializationContextBase
{
private readonly StringBuilder _builder;
private Dictionary