GH-3109: enable Polecat ancillary stores + generic [Storage] attribute#3112
Merged
Merged
Conversation
Enable the dormant Polecat ancillary-store integration (was dead code behind an undefined #if POLECAT_1_1) and add a provider-agnostic [Storage(Type)] attribute. Core (Wolverine.Persistence): - IAncillaryStoreFrameProvider: a seam each persistence integration registers so the generic [Storage(typeof(IStore))] attribute can route a handler to the store's outbox-enrolled session purely from the marker type (Marten, Polecat, EF Core later). - StorageAttribute + chain.UseAncillaryStorage(type, container) extension. - StorageAttributeEagerPolicy: Phase-A pre-population of chain.AncillaryStoreType (mirrors the per-provider eager policies; GH-2944 ordering). Marten: - MartenAncillaryStoreFrameProvider + chain.UseMartenStore(type); MartenStore attribute now routes through the shared extension (behavior unchanged). Polecat: - Removed the #if POLECAT_1_1 guards from the four ancillary files. - [PolecatStore] attribute, PolecatStoreEagerPolicy, PolecatAncillaryStoreFrame- Provider, chain.UsePolecatStore(type). - Ancillary PolecatOverrides<T> now wires PolecatToWolverineOutbox so inline- projection side effects on an ancillary store relay through the Wolverine outbox. Frame providers are registered in the primary IntegrateWithWolverine extension method (not *Integration.Configure) so the singleton is visible to the codegen- time IServiceContainer that StorageAttribute.Modify queries. Tests: full Polecat ancillary battery (bootstrap, separate SQL Server databases + multi-tenant, identity-URI uniqueness, inline-projection side effects, [Storage]) plus the Marten [Storage] mirror. Docs for both. Requires Polecat 4.5.0 (JasperFx/polecat#194) — AddPolecatStore<T> could not produce a typed store before that fix. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jun 15, 2026
This was referenced Jun 18, 2026
Merged
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.
Closes #3109.
Enables the dormant Polecat ancillary-store integration (dead code behind an undefined
#if POLECAT_1_1) and adds a provider-agnostic[Storage(Type)]attribute so a single attribute can route a handler to a Marten or Polecat ancillary store (EF Core later).Core (
Wolverine.Persistence)IAncillaryStoreFrameProvider— a seam each persistence integration registers so[Storage(typeof(IStore))]can resolve the owning provider purely from the store marker type.StorageAttribute+chain.UseAncillaryStorage(type, container).StorageAttributeEagerPolicy— Phase-A pre-population ofchain.AncillaryStoreType(mirrors the per-provider eager policies; Message from external system is stored in main store instead of ancillary store (ignoring [MartenStore] attribute at the message handler) #2944 ordering).Marten
MartenAncillaryStoreFrameProvider+chain.UseMartenStore(type).[MartenStore]now routes through the shared extension (behavior unchanged; all existing ancillary tests still pass).Polecat
#if POLECAT_1_1guards from the four ancillary files.[PolecatStore],PolecatStoreEagerPolicy,PolecatAncillaryStoreFrameProvider,chain.UsePolecatStore(type).PolecatOverrides<T>now wiresPolecatToWolverineOutboxso inline-projection side effects on an ancillary store relay through the Wolverine outbox (it was a no-op, so they were silently dropped).Frame providers are registered in the primary
IntegrateWithWolverineextension method (not*Integration.Configure) so the singleton is visible to the codegen-timeIServiceContainerthatStorageAttribute.Modifyqueries.Dependency
Requires Polecat 4.5.0 (JasperFx/polecat#194).
AddPolecatStore<T>hard-cast a bareDocumentStoreto the marker interface in every prior version, so it threwInvalidCastExceptionon resolution — the whole ancillary path could never have worked at runtime.Directory.Packages.propsis bumped to 4.5.0.Tests & docs
[PolecatStore]middleware, separate SQL Server databases + multi-tenant (MultiTenantedMessageStore), identity-URI uniqueness, inline-projection side effects relayed through the outbox, and[Storage]routing — 10 tests.[Storage]mirror.[Storage]sections on the Marten doc + sidebar.wolverine.slnxRelease build is clean (0/0) against published Polecat 4.5.0.🤖 Generated with Claude Code