[LOADED_DOCS: 3 files, no new loads]
Rename ShallowCopy to FlatCopy, add polymorph support - Renamed all "ShallowCopy" serializer presets and references to "FlatCopy" for clarity and consistency. - Expanded documentation to clarify flat serialization use cases, especially for delta-update and partial-write scenarios. - Added EnablePolymorphDetectFeature to AcBinarySerializableAttribute and updated all constructor overloads. - Set UsePolymorphType = true in AcBinarySourceGenerator to enable polymorphic type support by default. - Updated all [AcBinarySerializable(...)] usages to include new feature flags, explicitly disabling property filter and polymorph detection for affected types. - Improved comments and documentation for maintainability.
This commit is contained in:
parent
a7f2d3605b
commit
89618c1d10
|
|
@ -43,7 +43,7 @@ public class AcBinarySourceGenerator : IIncrementalGenerator
|
|||
// ────────────────────────────────────────────────────────────────────────────────────────────
|
||||
// UsePropertyFilter const removed — replaced by `[AcBinarySerializable(EnablePropertyFilterFeature = ...)]`
|
||||
// attribute flag, propagated through SerializableClassInfo.EnablePropertyFilter to EmitProp/EmitScanProp.
|
||||
private const bool UsePolymorphType = false;
|
||||
private const bool UsePolymorphType = true;
|
||||
|
||||
private static readonly DiagnosticDescriptor CircularReferenceWarning = new(
|
||||
id: "ACBIN001",
|
||||
|
|
|
|||
|
|
@ -31,26 +31,22 @@ public sealed class AcBinarySerializableAttribute : Attribute
|
|||
/// per-property filtering for this specific type.</para>
|
||||
/// </summary>
|
||||
public bool EnablePropertyFilterFeature { get; }
|
||||
public bool EnablePolymorphDetectFeature { get; }
|
||||
|
||||
public AcBinarySerializableAttribute() : this(true)
|
||||
{
|
||||
}
|
||||
|
||||
public AcBinarySerializableAttribute(bool enableAllFeatures)
|
||||
{
|
||||
EnableMetadataFeature = enableAllFeatures;
|
||||
EnableIdTrackingFeature = enableAllFeatures;
|
||||
EnableRefHandlingFeature = enableAllFeatures;
|
||||
EnableInternStringFeature = enableAllFeatures;
|
||||
EnablePropertyFilterFeature = enableAllFeatures;
|
||||
}
|
||||
public AcBinarySerializableAttribute(bool enableAllFeatures) : this(enableAllFeatures, enableAllFeatures, enableAllFeatures, enableAllFeatures, enableAllFeatures, enableAllFeatures)
|
||||
{ }
|
||||
|
||||
public AcBinarySerializableAttribute(bool enableMetadataFeature, bool enableIdTrackingFeature, bool enableRefHandlingFeature, bool enableInternStringFeature, bool enablePropertyFilterFeature)
|
||||
public AcBinarySerializableAttribute(bool enableMetadataFeature, bool enableIdTrackingFeature, bool enableRefHandlingFeature, bool enableInternStringFeature, bool enablePropertyFilterFeature, bool enablePolymorphDetectFeature)
|
||||
{
|
||||
EnableMetadataFeature = enableMetadataFeature;
|
||||
EnableIdTrackingFeature = enableIdTrackingFeature;
|
||||
EnableRefHandlingFeature = enableRefHandlingFeature;
|
||||
EnableInternStringFeature = enableInternStringFeature;
|
||||
EnablePropertyFilterFeature = enablePropertyFilterFeature;
|
||||
EnablePolymorphDetectFeature = enablePolymorphDetectFeature;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,10 +34,10 @@ public sealed class AcBinarySerializerOptions : AcSerializerOptions
|
|||
};
|
||||
|
||||
/// <summary>
|
||||
/// Options for shallow serialization (root level only).
|
||||
/// Options for flat serialization (root level only).
|
||||
/// Returns a new instance each time to prevent shared state corruption.
|
||||
/// </summary>
|
||||
public static AcBinarySerializerOptions ShallowCopy => new()
|
||||
public static AcBinarySerializerOptions FlatCopy => new()
|
||||
{
|
||||
MaxDepth = 0,
|
||||
// Truncate preserves the original "root + Null nested" semantic; under default Throw the preset
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ Key wire-format options: `WireMode` (Compact/Fast), `ReferenceHandling` (None/On
|
|||
|
||||
`ReferenceHandling=None` + `UseStringInterning=None` = no scan pass (single-phase, fastest).
|
||||
|
||||
Presets: `Default`, `FastMode`, `ShallowCopy`, `WasmOptimized`. Details: `docs/BINARY/BINARY_OPTIONS.md`.
|
||||
Presets: `Default`, `FastMode`, `FlatCopy`, `WasmOptimized`. Details: `docs/BINARY/BINARY_OPTIONS.md`.
|
||||
|
||||
## Dependencies
|
||||
|
||||
|
|
|
|||
|
|
@ -16,10 +16,10 @@ public sealed class AcJsonSerializerOptions : AcSerializerOptions
|
|||
public static AcJsonSerializerOptions Default => new() { ReferenceHandling = ReferenceHandlingMode.All };
|
||||
|
||||
/// <summary>
|
||||
/// Options for shallow serialization (root level only, no references).
|
||||
/// Options for flat serialization (root level only, no references).
|
||||
/// Returns a new instance each time to prevent shared state corruption.
|
||||
/// </summary>
|
||||
public static AcJsonSerializerOptions ShallowCopy => new() { MaxDepth = 0, ReferenceHandling = ReferenceHandlingMode.None };
|
||||
public static AcJsonSerializerOptions FlatCopy => new() { MaxDepth = 0, ReferenceHandling = ReferenceHandlingMode.None, MaxDepthBehavior = MaxDepthBehavior.Truncate};
|
||||
|
||||
/// <summary>
|
||||
/// Creates options with specified max depth.
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ Custom JSON serialization/deserialization built on `System.Text.Json`'s `Utf8Jso
|
|||
| `MaxDepth` | Maximum object graph depth |
|
||||
| `ThrowOnCircularReference` | Throw vs silently handle circular refs |
|
||||
|
||||
**Presets:** `Default` (with refs), `ShallowCopy`, `WithMaxDepth`, `WithoutReferenceHandling`.
|
||||
**Presets:** `Default` (with refs), `FlatCopy`, `WithMaxDepth`, `WithoutReferenceHandling`.
|
||||
|
||||
## Dependencies
|
||||
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ The shallow-serialization use case is a legitimate, common pattern (client edits
|
|||
- `Truncate` — the previous `WriteByte(Null)` behavior, now explicit opt-in for shallow serialization (delta updates, view-model projections, partial DB-update flows). The wire `Null` at the truncation boundary is the developer's contract decision — endpoint protocol dictates what nested null means. Works with any persistence layer (Dapper, ADO.NET, Cosmos DB, MongoDB, Redis, EF Core, etc.).
|
||||
- `Disable` — skip the depth check entirely (max perf, dev guarantees cycle-free graph).
|
||||
|
||||
The check moved from "every object/collection write" (with rewind) to "before any marker byte is written" (in `WriteObject` runtime + `WriteObjectFullMarker*` SGen). The `ShallowCopy` preset was updated to explicitly set `MaxDepthBehavior = Truncate` to preserve its original "root + Null nested" semantic. See `BINARY_OPTIONS.md` `MaxDepth + MaxDepthBehavior` section for full details.
|
||||
The check moved from "every object/collection write" (with rewind) to "before any marker byte is written" (in `WriteObject` runtime + `WriteObjectFullMarker*` SGen). The `FlatCopy` preset was updated to explicitly set `MaxDepthBehavior = Truncate` to preserve its original "root + Null nested" semantic. See `BINARY_OPTIONS.md` `MaxDepth + MaxDepthBehavior` section for full details.
|
||||
|
||||
### ACCORE-BIN-I-W3F4: PropertyFilter + UseMetadata=false silently corrupts via index drift
|
||||
|
||||
|
|
|
|||
|
|
@ -146,14 +146,14 @@ delegate PropertyInfo? PropertyMapperDelegate(PropertyInfo sourceProperty, Type
|
|||
|--------|----------|----------|-----------------|-------------|----------|------------------|-------------|-------|
|
||||
| `Default` | Compact | false | Attribute | All | 255 | Throw | None | — |
|
||||
| `FastMode` | Compact | false | None | None | 255 | Throw | None | No scan pass |
|
||||
| `ShallowCopy` | Compact | false | None | None | **0** | **Truncate** ⚠️ | None | Root + Null nested (the Truncate behavior makes this preset's semantic meaningful — under default `Throw` it would throw on first nested object) |
|
||||
| `FlatCopy` | Compact | false | None | None | **0** | **Truncate** ⚠️ | None | Root + Null nested (the Truncate behavior makes this preset's semantic meaningful — under default `Throw` it would throw on first nested object) |
|
||||
| `WasmOptimized` | Compact | false | Attribute | All | 255 | Throw | None | +StringCaching |
|
||||
| `WithoutReferenceHandling` | Compact | false | Attribute | **None** | 255 | Throw | None | No scan pass |
|
||||
| `WithoutMetadata` | Compact | **false** | Attribute | All | 255 | Throw | None | — |
|
||||
|
||||
**Performance implication of presets:**
|
||||
- `Default` / `WasmOptimized` — two-phase (scan + serialize) due to `ReferenceHandling=All`
|
||||
- `FastMode` / `ShallowCopy` — single-phase (no scan pass) since both interning and refs are disabled
|
||||
- `FastMode` / `FlatCopy` — single-phase (no scan pass) since both interning and refs are disabled
|
||||
- The scan pass adds ~20-30% overhead; disable it when the object graph is a simple tree
|
||||
|
||||
## Option Interactions
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue