Annotate DocumentStore.ProjectionReplay.cs reflective surface for AOT (closes #71)#75
Merged
Merged
Conversation
…closes #71) Second Polecat AOT-pillar slice (polecat#71), mirroring the methodology that landed in JasperFx #252-#255 + #260 + polecat#74. Annotated surfaces RunProjectionForReferenceTypeAsync<TState> — [RUC] + [RDC] (private; runs the aggregator graph + STJ event deserialize) ToDomainEvent(EventRecord) — [RUC] + [RDC] (resolves CLR type from event name + STJ FromJson) ResolveEventClrType(string eventTypeName) — [RUC] (walks AppDomain assemblies + Assembly.GetTypes) Suppressed at explicit interface impls IEventStore.RunProjectionAsync<TState> — IL2091 + IL3050 + IL2075 + IL2026 IEventStore.RunProjectionByNameAsync — IL3050 + IL2026 + IL2075 Why suppress instead of annotate Both methods are explicit interface implementations of `IEventStore` (in JasperFx.Events). Adding [RequiresUnreferencedCode] to the impl would generate IL2046 because the interface contract on IEventStore.RunProjectionAsync / RunProjectionByNameAsync isn't yet annotated. The Events-side annotation is tracked in jasperfx#262; when those interfaces gain [RUC] / [RDC], the Polecat suppressions here can be replaced with matching annotations. Justifications point at the design intent: projection step-through is a dev-time / diagnostic surface used by CritterWatch + projection replay, not a hot-path runtime API. AOT-publishing apps either avoid the surface entirely or supply a source-generated dispatcher. Effect on the punch list (per TFM) ProjectionReplay slice: 48 → 0 (closed) Polecat total: 422 → 374 (-48) Note the slice grew from the originally-filed 44 to 48 between the issue filing and this PR — propagation from polecat#74's Serializer slice surfaced 4 new IL3050 warnings on the FromJson call site that this PR also addresses. Verification Polecat.csproj + Polecat.Tests.csproj build clean (0 errors) Closes #71.
This was referenced May 13, 2026
jeremydmiller
added a commit
that referenced
this pull request
May 13, 2026
Two updates to keep the migration-guide accurate as the 2026-wave alphas roll forward: - Bump the foundation-pin table to current Polecat 4 alpha versions: JasperFx alpha.8 → alpha.11, JasperFx.Events alpha.3 → alpha.4, Weasel.* alpha.2 → alpha.3. Note that the alpha line is still rolling forward and consumers should pin all five together. - Rewrite the AOT / codegen posture section to reflect the actual landed state: IsAotCompatible=true is set on the Polecat assembly (#67), and the reflective surfaces have been progressively annotated through #74 (serialization), #75 (projection replay), #76 (LINQ extension/provider), and #77 (storage / registry / event-store explorer). Link out to the cross-stack "Publishing AOT with JasperFx" guide on jasperfx.github.io for the end-to-end walkthrough. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3 tasks
jeremydmiller
added a commit
that referenced
this pull request
May 13, 2026
Fifth slice in Polecat's AOT-pillar (jasperfx#213) cleanup, following the Serializer (#74), ProjectionReplay (#75), LINQ (#76), and Storage/Registry (#77) slices that have landed on main. The patching subsystem reflects on the document's property expressions to build JSON path strings and feeds the resulting patch values through ISerializer.ToJson when emitting JSON_MODIFY() SQL. JsonPathHelper also compiles small Expression.Lambda delegates to evaluate constant sub- expressions during path resolution. Document types T flow in from Schema.For<T>() / IDocumentSession.Patch<T>() at the registration boundary and are preserved per the AOT publishing guide; AOT consumers supply a source-generator-backed ISerializer impl. Apply class-level [UnconditionalSuppressMessage] with justifications: - Patching/PatchExpression<T>: IL2026/IL3050 (ISerializer.ToJson on patch values) - Patching/PatchOperation: IL2026/IL3050 (ISerializer.ToJson when building JSON_MODIFY commands) - Patching/JsonPathHelper: IL3050 (Expression.Lambda for constant sub-expression evaluation) 194 → 152 unique IL warnings (-42) in Polecat.csproj. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Second Polecat AOT-pillar slice (closes #71), mirroring the methodology that landed in JasperFx #252-#255 + #260 + polecat#74.
Annotated surfaces
RunProjectionForReferenceTypeAsync<TState>(private)[RequiresUnreferencedCode]+[RequiresDynamicCode]— runs the aggregator graph + STJ event deserializeToDomainEvent(EventRecord)(private)[RequiresUnreferencedCode]+[RequiresDynamicCode]— resolves CLR type from event name + STJ FromJsonResolveEventClrType(string eventTypeName)(private)[RequiresUnreferencedCode]— walks AppDomain assemblies +Assembly.GetTypes()Suppressed at explicit interface impls
IEventStore.RunProjectionAsync<TState>IEventStore.RunProjectionByNameAsyncWhy suppress instead of annotate
Both methods are explicit interface implementations of
IEventStore(in JasperFx.Events). Adding[RequiresUnreferencedCode]to the impl would generate IL2046 because the interface contract onIEventStore.RunProjectionAsync/RunProjectionByNameAsyncisn't yet annotated. The Events-side annotation is tracked in jasperfx#262; when those interfaces gain[RequiresUnreferencedCode]/[RequiresDynamicCode], the Polecat suppressions here can be replaced with matching annotations.Justifications point at the design intent: projection step-through is a dev-time / diagnostic surface used by CritterWatch + projection replay, not a hot-path runtime API. AOT-publishing apps either avoid the surface entirely or supply a source-generated dispatcher.
Effect on the punch list
Note the slice grew from the originally-filed 44 to 48 between issue filing and this PR — propagation from polecat#74's Serializer slice surfaced 4 new IL3050 warnings on the
FromJsoncall site that this PR also addresses.Verification
Polecat.csproj+Polecat.Tests.csprojbuild clean (0 errors)Closes #71.
🤖 Generated with Claude Code