| Name | Modified | Size | Downloads / Week |
|---|---|---|---|
| Parent folder | |||
| README.md | 2026-04-25 | 20.9 kB | |
| v13.0.0 source code.tar.gz | 2026-04-25 | 735.4 kB | |
| v13.0.0 source code.zip | 2026-04-25 | 974.6 kB | |
| Totals: 3 Items | 1.7 MB | 1 | |
v13.0.0
This is a major release with 368 files changed across the entire Foundatio codebase. Here are the themes that define v13:
- Reliability & Correctness: Dozens of race conditions, deadlocks, and disposal issues have been hunted down and fixed across queues, messaging, caching, and timers. Cancellation tokens are now properly linked to disposal for clean shutdown, and poison messages are gracefully handled instead of crashing consumers.
- Consistent Error Handling: Every subsystem now has its own exception type (
QueueException,MessageBusException,SerializerException) so consumers get predictable, catchable errors regardless of the underlying provider. These feature-specific exceptions are automatically excluded from resilience policy retries. - API Normalization: Cache TTL behavior, serializer validation, and expiration return values have been normalized across all implementations -- no more provider-specific quirks.
- Null Safety: A comprehensive NRT audit eliminated
null!suppressions across the codebase, fixing latent null bugs and adding proper nullable attributes. The API surface now accurately communicates nullability contracts. - Modern .NET: Dropped
netstandard2.0in favor ofnet8.0+net10.0. Replaced DeepCloner with the actively-maintained FastCloner.ScheduledTimernow usesTimeProviderfor testability. - Documentation Overhaul: Foundatio now has a dedicated documentation site with comprehensive guides, source code links, and real-world examples for every subsystem.
Documentation Site
Foundatio v13 ships with a brand-new documentation site covering every subsystem with guides, configuration examples, and direct source code links. Key additions:
- New docs site built with VitePress (
061bd763) - Source code links added to every subsystem: caching (
8f6d37c1), queues (bb9af714), messaging (59cc2f57), locks (10241465), jobs (7df97b13), serialization (8819ba09), storage (bf2eb1b9) - Comprehensive hybrid caching documentation with RedisHybridCacheClient examples (
2fc124df,0791b496) - Cache stampede protection patterns (
a6cfd75c) - Delayed message delivery and distributed tracing guide (
da2c6162) - RabbitMQ delayed delivery and delayed-exchange plugin deprecation notes (#490)
- Redis read routing and replica support guide (
6860a0c1) - Redis replication lag risk documentation (
98323dbe) - Queue names vs. queue IDs explainer (
456389ed) - Cancellation token behavior clarification (
70a63d12) - Cache expiration differences across implementations (
1853daee) - Enhanced XML doc comments across all core interfaces (
7fdad859) - Updated job samples (
3e003a86) and added sample projects + benchmarks to the solution (160dd74f) - Added Foundatio.Mediator (github.com) links to README and docs (
b8f0eba1)
Breaking Changes
- Dropped
netstandard2.0target: Foundatio now targetsnet8.0andnet10.0only. Consumers on .NET Framework or older runtimes must stay on v12.x. by @niemyjski in4c6aefed,a1089422 - Normalized
ICacheClient.IncrementAsyncTTL behavior: Increment operations now consistently apply the TTL parameter across all implementations. RemovedListRemoveAsyncExpiresInargument to align with all other Remove methods. by @niemyjski in #434 - Normalized
ICacheClientreturn values for expiration:GetExpirationAsyncreturns consistent values across implementations. by @niemyjski in #432 - Normalized
ISerializerargument validation: All serializer implementations now consistently validate arguments and throwArgumentException/ArgumentNullException. by @niemyjski in #440 - Added
QueueException: Queue operations now throwQueueExceptionfor queue-specific errors. Guard added against reusing behavior instances. by @niemyjski in #448 MessageBusIdandQueueIdchanged to init-only properties: These properties can no longer be set after construction. by @niemyjski inb73bf128- Removed obsolete
Set/SetAdd/SetRemovemethods from cache extensions: These were renamed toList*in v9.0.0 (Nov 2019) and have been[Obsolete]for 6+ years. by @niemyjski in150beed5 - Removed obsolete single-parameter
GetFileStreamAsyncoverload: Deprecated in v10.7.0 (Jan 2024) whenStreamModewas added. Use the overload acceptingStreamModeandCancellationToken. by @niemyjski in037baae5 - Comprehensive NRT (Nullable Reference Types) null-safety audit: Eliminated
null!suppressions, fixed latent null bugs, and added nullable attributes across the codebase. Return types and parameters may have changed nullability. by @niemyjski in #484, #498
Added
- Upgrade to xUnit v3 with
Foundatio.Xunit.v3: Test infrastructure upgraded to xUnit v3. NewFoundatio.Xunit.v3package with retry test attributes (RetryFactAttribute,RetryTheoryAttribute) for automatic retry of flaky tests. The existingFoundatio.Xunitpackage continues to support xUnit v2. by @niemyjski in #431 - Memory-limited in-memory cache:
InMemoryCacheClientnow supportsMaxMemorySizewith per-entry size limits and intelligent eviction when memory budgets are exceeded. by @niemyjski, @copilot in #400 - Poison message handling for queues and message bus: Deserialization failures in queues and the message bus are now gracefully handled as poison messages instead of crashing consumers. Dead letter logging improved. by @niemyjski in #455
SerializerException: New exception type for serialization-specific errors, enabling targeted error handling. by @niemyjski inb314a052MessageBusException: Consistent error handling for messaging operations with improved delayed message delivery. by @niemyjski in #443QueueDeletedevent onIQueue<T>: Consumers can now subscribe to queue deletion notifications. by @niemyjski in #447- OpenTelemetry error recording: Added
Activity.AddExceptionpolyfill for recording exceptions in distributed traces across all target frameworks. by @niemyjski in #446 - Synchronous
IResiliencePolicymethods: Added sync overloads (Execute,ExecuteAsync) alongside existing async methods. by @ejsmith in #445 - Feature-specific exceptions excluded from resilience policy retries:
QueueException,MessageBusException,StorageException,SerializerException, andCacheExceptionare no longer retried by resilience policies. by @niemyjski in318fa1a0 GetAllExpirationsAsyncandSetAllExpirationsAsynconICacheClient: Bulk expiration read/write support with improved test coverage. by @niemyjski in #426- Option to dispose underlying scoped implementations: Scoped cache/queue/etc. wrappers can now optionally dispose their underlying instances. by @niemyjski in #412
- Job status description:
JobStatusnow supports aDescriptionproperty. by @ejsmith infdcc1442 - Enforce 5ms minimum expiration across all cache implementations: Prevents extremely short TTLs that cause race conditions. by @niemyjski in #463
net10.0target framework: Added .NET 10 support alongside .NET 8. by @niemyjski in4c6aefed,a1089422- Delayed message delivery: Message bus now supports delayed/scheduled message publishing. by @niemyjski in #443
TestCancellationTokenin test harness: Added toTestLoggerBaseandTestWithLoggingBase(v2 and v3) for better test cancellation support. by @niemyjski inc37508ef,d24afcb7- Scoped cache constructor overload: New
ScopedCacheClientconstructor that defaultsshouldDisposetofalseto prevent accidental disposal. by @niemyjski inf28463b9
Changed
- Replaced DeepCloner with FastCloner: Switched deep cloning implementation from DeepCloner to FastCloner (v3.5.3) for better performance and active maintenance. Huge thanks to @lofcz (Matej Stagl) for contributing FastCloner and helping integrate it into Foundatio -- this was a major effort that touched the deep internals of the cloning infrastructure. by @niemyjski, @lofcz in #469, #485
- HybridCacheClient subscription moved out of constructor: Uses
AsyncLazyto avoid sync-over-async in constructors. by @niemyjski in7050c523 - Improved HybridCacheClient consistency and invalidation: Fixed consistency issues, optimized invalidation, and improved double comparison logic. by @niemyjski in #433
ScheduledTimerusesTimeProvider: Scheduled jobs now useTimeProviderfor delays, improving testability. by @niemyjski in77727cdf- Two-phase dispose for MessageBus subscription lifecycle: More reliable shutdown behavior. by @niemyjski in #492
- Cancellation tokens linked to disposal: MessageBus and Queue now link cancellation tokens to disposal for prompt shutdown. by @niemyjski in
c06fcdef - Improved disposal logic consistency: Disposal guards,
IsDisposedconsolidation, and properCancellationTokenSourcedisposal across all base classes. by @niemyjski in49eec83a,be62be11 - Enhanced
MessageOptions: Added XML documentation and support for custom properties. by @niemyjski in692c644d - Refactored
DataDictionary: UsesTryGetValue, nullable returns, and switch expressions. by @niemyjski in2b423514 - Comprehensive XML documentation: Enhanced docs across
ICacheClient,IQueue,IMessageBus,IFileStorage,ILockProvider, andIJobinterfaces. by @niemyjski in7fdad859 - Lock providers accept
TimeProviderandIResiliencePolicyProvider:CacheLockProviderandThrottlingLockProvidernow receive dependencies via constructor injection for improved testability and resilience. by @niemyjski ine3e815c4 - Improved async timeout handling: Refactored
AsyncCountdownEventto useWaitAsyncconsistently;QueueTestBasenow implementsIAsyncDisposable. by @niemyjski ind78f220d - Updated dependencies: Microsoft.Extensions packages, BenchmarkDotNet, Aspire, Polly, and others updated to latest versions. by @niemyjski, @ejsmith
Fixed
- Race condition in
InMemoryQueue.AbandonAsync: Fixed flakyRunUntilEmptyAsynccaused by abandon race. by @niemyjski in #470 InvalidCastExceptioninInMemoryCacheClient.GetAsync<object>(): Fixed crash for non-IConvertibletypes. by @copilot in #468- Race condition in
ScheduledTimer: Fixed timing issue in scheduled timer callbacks. by @niemyjski in65e3116a - Race condition in
HybridCacheClientinvalidation tests: Fixed flaky test caused by invalidation timing. by @niemyjski in5acce8bc InMemoryQueueretry entry isolation: Each retry attempt now creates a fresh queue entry, preventing state leakage between attempts. by @niemyjski in #454- Sync-over-async deadlock in
MessageBusBase: Fixed deadlock inCancellationToken.Registercallback. by @niemyjski infdc47d22 ThrottlingLockProviderperiod boundary issues: Hardened spin-wait withString.Equals, iteration cap, and improved diagnostics. by @niemyjski ind619b7e3,bbca0e39IndexOutOfRangeExceptionin FastClonerGenerateProcessSetMethod: Fixed array bounds issue in deep cloning. by @niemyjski inf1992944ArgumentOutOfRangeExceptioninDoMaintenance: Prevented negative timespan in queue maintenance scheduling. by @niemyjski inee00d141DateTimeoverflow in cache maintenance: AddedSafeAddextension methods to prevent overflow exceptions when adding toDateTime.MaxValue/DateTime.MinValue. by @niemyjski in6df04edf- Zero or negative expiration in
ReplaceIfEqualAsync: Now correctly removes the key instead of setting an invalid TTL. by @niemyjski inffc8d352 - Null/empty connection strings in
ConnectionStringParser: Now handled gracefully instead of throwing. by @niemyjski indf7c6898 FaultInjectingSerializermissingITextSerializer: Now implementsITextSerializerto prevent unexpected Base64 encoding in tests. by @niemyjski in87fdf6e3- Flaky metrics test: Fixed timer resolution race with
DateTime.UtcNow. by @niemyjski in #488 - Queue metrics when disposed: Returns empty metrics instead of throwing. by @lofcz in
4744fc1b
New Contributors
Huge shoutout to @lofcz (Matej Stagl) for his outstanding contributions to this release! Matej is the author of FastCloner, which replaces DeepCloner as Foundatio's deep cloning engine. He contributed the integration PRs (#469, #485), kept FastCloner in sync with upstream improvements, and fixed a queue metrics edge case -- all while being incredibly responsive and collaborative. Thank you, Matej!
- @niemyjski
- @ejsmith
- @lofcz (Matej Stagl) -- FastCloner author and integration contributor
- @copilot
Migration Guide
Target Framework Changes
v13 drops netstandard2.0 and targets net8.0;net10.0. If you are on .NET Framework, you must stay on Foundatio v12.x.
Cache API Changes
IncrementAsyncTTL: The TTL parameter now behaves consistently across all cache implementations. Review any code that relied on implementation-specific TTL behavior during increment operations.ListRemoveAsync: TheExpiresInparameter has been removed. If you were passing an expiration toListRemoveAsync, remove that argument.GetExpirationAsync: Return values are now normalized. Test any code that compared expiration values across implementations.- Minimum expiration: All cache implementations now enforce a 5ms minimum expiration. Values below 5ms will be clamped.
Serializer Changes
- All
ISerializerimplementations now validate arguments consistently. If your code was passingnullto serializer methods, you will now getArgumentNullException. SerializerExceptionis now thrown for serialization-specific failures. Update anycatchblocks that were catching general exceptions from serializers.
Queue Changes
- Queue operations now throw
QueueExceptionfor queue-specific errors. Update exception handling accordingly. - Queue behavior instances (e.g.,
IQueueBehavior<T>) can no longer be reused across multiple queue instances. - Poison messages (deserialization failures) are now routed to dead letters instead of crashing consumers. Review dead letter handling if you rely on immediate failure notification.
Messaging Changes
MessageBusExceptionis now thrown for messaging errors. Update exception handling.MessageBusIdandQueueIdare now init-only. Set them during construction only.
Nullable Reference Types
- Many APIs have updated nullability annotations. If you have NRT enabled, expect new warnings that reflect the corrected nullability contracts. These are accurate -- the previous annotations were incorrect.
Removed APIs
CacheClientExtensions.Set/SetAdd/SetRemove(obsolete overloads) -- These were renamed toListAdd/ListRemoveback in v9.0.0 (November 2019) to avoid confusion between "set" as a verb and "set" as a data structure. The old names have been marked[Obsolete]for over 6 years across 4 major versions. Use theList*equivalents.IFileStorage.GetFileStreamAsync(string path)(single-parameter overload) -- Deprecated in v10.7.0 (January 2024) when write-capable file streams were added in #290, which introduced an overload acceptingStreamModeandCancellationToken. The single-parameter version has been[Obsolete]for 2+ years. UseGetFileStreamAsync(path, StreamMode.Read, cancellationToken)instead.
Full Changelog: https://github.com/FoundatioFx/Foundatio/compare/v12.0.0...v13.0.0