Skip to main content
Version: 3.1.1

Changelog

The authoritative release history for all RCommon packages is maintained on GitHub Releases.

Full release notes: https://github.com/RCommon-Team/RCommon/releases

Recent Changes

3.1.1

Bug-fix and security patch release.

Fixed

  • Cross-host transactional outbox delivery. Added OutboxOptions.ImmediateDispatch (default true, fully backward-compatible). When set to false, a unit of work persists outbox events but skips the best-effort post-commit in-process dispatch (Phase 3), leaving the durable poller (OutboxProcessingService) as the sole dispatcher and marker. This fixes silent loss of cross-host delivery, where a producing host marked rows processed before a subscriber on a different host could consume them. Producer-only hosts should set ImmediateDispatch = false. See Outbox Producer/Processor Topology.
  • Outbox post-commit dispatch no longer marks a message processed when no in-process producer matched the event; it is left for the poller (defense-in-depth).
  • EFCoreOutboxStore.DeleteProcessedAsync / DeleteDeadLetteredAsync used a DateTimeOffset comparison the SQLite provider could not translate. The comparison is now evaluated client-side; SQL Server / PostgreSQL behaviour is unchanged.

Security

  • Pinned patched Microsoft.OpenApi 2.7.5 in RCommon.Authorization.Web (net10 target), resolving CVE-2026-49451 (GHSA-v5pm-xwqc-g5wc), which was pulled transitively via Swashbuckle 10.x.
  • Upgraded the native SQLite binary (SQLitePCLRaw.lib.e_sqlite3 3.53.3) in the SQLite-backed test projects, resolving CVE-2025-6965 (GHSA-2m69-gcr7-jv3q).

Notes

  • Strictly additive public API surface (OutboxOptions.ImmediateDispatch); no signature removals, and no behavioural change at the default.
  • Website (Docusaurus) build-tooling npm advisories are tracked as a separate follow-up (Docusaurus 3.10 upgrade + theme swizzle migration).

Modular Composition (Unreleased)

Added support for calling services.AddRCommon() from multiple modules in the same process. Registrations merge instead of duplicating or throwing on agreement.

Added

  • Modular composition supportservices.AddRCommon() can now be called from multiple modules in the same process. Registrations merge instead of duplicating or throwing on agreement. See Modular Composition.
  • New public API: IRCommonBuilder.GetOrAddBuilder<TSubBuilder>(Func<TSubBuilder>) — third-party WithX<T> extensions opt into sub-builder caching.
  • New public API: IRCommonBuilder.GetBootstrapDiagnostics() — retrieve the soft-duplicate report stashed at host startup.
  • New public API: IServiceCollection.IsRCommonInitialized() — true iff AddRCommon() has been called.
  • New internal IHostedService runs the duplicate-descriptor scanner at host startup and emits a single warning on soft duplicates.

Changed

  • AddRCommon() is now idempotent: subsequent calls return the cached IRCommonBuilder.
  • Singleton-style verbs (WithSimpleGuidGenerator, WithSequentialGuidGenerator, WithDateTimeSystem, WithJsonSerialization<T>, WithSmtpEmailServices, WithSendGridEmailServices) are now idempotent on same-type re-registration. Different-type conflicts throw RCommonBuilderException with diagnostic messages.
  • DataStoreFactoryOptions.Register<,> is now idempotent for identical (name, base, concrete) triples. Conflicts (same (name, base) with different concrete) throw UnsupportedDataStoreException (exception type preserved).
  • AddProducer<T> now deduplicates by concrete producer type via descriptor scan — distinct producer types still coexist.
  • All sub-builder WithX<T> extensions route through GetOrAddBuilder<T>; generic constraints tightened to where T : class, ....

Notes

  • Strictly additive public API surface. No method or interface signature removals.
  • No exception types changed on existing APIs.
  • See Examples/Bootstrapping/Examples.Bootstrapping.MultiModule/ for a runnable demonstration.

Blob Storage Abstractions

Added RCommon.Blobs as a provider-agnostic blob storage abstraction layer, with two concrete implementations:

  • RCommon.Azure.Blobs — Azure Blob Storage implementation
  • RCommon.Amazon.S3Objects — Amazon S3 implementation

Multi-Tenancy Support

Added complete multi-tenancy infrastructure:

  • RCommon.MultiTenancy — builder abstraction for registering tenancy providers via WithMultiTenancy<T>()
  • RCommon.Finbuckle — Finbuckle.MultiTenant integration, providing FinbuckleTenantIdAccessor<TTenantInfo> that bridges Finbuckle's resolved tenant context to the ITenantIdAccessor consumed by all repositories
  • All persistence providers (EFCoreRepository, DapperRepository, Linq2DbRepository) automatically filter reads by tenant and stamp writes with the current tenant ID when entities implement IMultiTenant

Domain-Driven Design Support

Added soft delete and multitenancy to the entity layer:

  • ISoftDelete — opt-in interface for logical deletion; repositories set IsDeleted = true and perform an UPDATE instead of a physical DELETE
  • IMultiTenant — opt-in interface for tenant-scoped entities; repositories filter reads and stamp writes automatically
  • SoftDeleteHelper and MultiTenantHelper utility classes for filter expression building and entity stamping
  • EntityNotFoundException for consistent "entity not found" error handling with type and ID context

Repository Soft Delete Extras

Extended all persistence providers with explicit soft delete and bulk operation support:

  • DeleteAsync(entity, isSoftDelete: bool) overload on all write repositories
  • Automatic !IsDeleted filtering on all read operations for ISoftDelete entities
  • Bulk delete via ExecuteDeleteAsync on EFCoreRepository

Editorconfig and Code Hygiene

Added .editorconfig to enforce consistent code style across the solution. All public methods and complex code paths now carry XML documentation comments.

Versioning

RCommon uses MinVer for automatic semantic versioning from git tags. All packages in the solution share the same version number.

Version numbers follow Semantic Versioning:

  • Major (x.0.0) — breaking API changes
  • Minor (0.x.0) — new features, backward-compatible additions
  • Patch (0.0.x) — bug fixes and documentation updates

Pre-release versions (alpha, beta, rc) are tagged accordingly (e.g., v3.0.0-alpha.1).

Release Schedule

RCommon does not follow a fixed release cadence. Releases are made when meaningful features, bug fixes, or breaking changes are ready. Subscribe to GitHub Releases or watch the repository to be notified of new versions.

Filing Issues

Found a bug or missing a feature? Please open an issue on GitHub:

RCommonRCommon