Skip to content

Releases: Maxofpower/FeatureFusion

BuildingBlocks.Pagination.EntityFrameworkCore v1.0.0

Choose a tag to compare

@Maxofpower Maxofpower released this 30 Aug 14:58
217e16f

BuildingBlocks.Pagination v1.0.0

Production-oriented cursor pagination for .NET 8 / 9 / 10, built around keyset pagination with typed sort keys, composite ordering, forward/backward navigation, opaque cursors, EF Core and Dapper support, cancellation, optional total counts, and provider-aware query behavior.

The library avoids string-based/reflection-driven sort selection and keeps pagination rules explicit, typed, and testable.

What's Included

  • Typed sorting with SortKey / SortKeyRegistry
  • Keyset pagination with composite keys and unique tie-breakers
  • Forward and backward navigation with NextCursor / PreviousCursor
  • Last-page navigation using PageDirection.Backward
  • Opaque cursor encoding and validation
  • Optional HMAC cursor signing
  • Optional total counts with IncludeTotalCount
  • CancellationToken throughout EF Core and Dapper execution
  • Nullable string ordering with NullOrder
  • HasKeysetIndex for recommended composite indexes
  • Provider-aware QueryHint with a deliberately small allowlist

EF Core

  • ToCursorPageAsync(...) for keyset pagination
  • Typed SortKey / SortKeyRegistry instead of runtime property-name reflection
  • Composite ordering such as Price + Id, Name + Id, and CreatedAt + Id
  • Forward and backward cursor navigation
  • Optional COUNT + PAGE
  • SQL Server ReadUncommitted support
  • Explicit restoration of READ COMMITTED after SQL Server hint operations
  • PostgreSQL and SQLite treat the SQL Server-only hint as a no-op

Dapper

  • QueryCursorPageAsync(...)
  • Same cursor/keyset model as the EF Core adapter
  • SQL Server-specific query-hint handling
  • COUNT and page queries receive the same hint behavior

Dapper remains an in-repository adapter and is not packed into this NuGet package.

FeatureFusion Showcase

FeatureFusion provides a runnable integration showcase using a real PostgreSQL product catalog.

The same GetProductsQuery powers:

  • GET /api/v2/products-page
  • POST /api/v2/products-page
  • POST /api/v2/Product/products
  • POST /api/v2/Product/products-dapper
  • MCP products.list

The catalog demonstrates typed product sort keys, composite Price + Id, Name + Id, and CreatedAt + Id ordering, unique tie-breakers, forward/backward navigation, first-page totals, last-page navigation, opaque cursors, cancellation, and EF Core + Dapper against the same PostgreSQL data.

Cursor navigation

First page:

GET /api/v2/products-page?limit=20&sortBy=Price&sortDirection=Ascending

Next page:

GET /api/v2/products-page?limit=20&sortBy=Price&sortDirection=Ascending&cursor=<NextCursor>

Previous page:

GET /api/v2/products-page?limit=20&sortBy=Price&sortDirection=Ascending&cursor=<PreviousCursor>

Last page:

GET /api/v2/products-page?limit=20&pageDirection=Backward

Cursors are opaque and should be returned unchanged.

Performance Validation

The repository includes a reproducible --probe using large SQLite datasets from the FeatureFusion benchmark catalog.

Returned IDs are validated against a live OFFSET query before timing. The validation itself is not timed.

10M rows, skip 5M

  • OFFSET: 154.9 ms
  • FeatureFusion keyset: 17.8 ms
  • MR: 19.9 ms

100M rows, skip 50M

  • OFFSET: 2470.4 ms
  • FeatureFusion keyset: 177.2 ms
  • MR: 218.0 ms

These are Stopwatch probe results from the FeatureFusion benchmark catalog on the documented hardware. They are not universal performance claims, and SQLite results should not be interpreted as SQL Server or PostgreSQL performance results.

At a 50M-row skip in this catalog, FeatureFusion keyset pagination measured approximately 14x faster than OFFSET in this particular probe.

QueryHint

QueryHint intentionally exposes only:

  • None
  • ReadUncommitted

For SQL Server:

  • EF Core uses one ReadUncommitted transaction around COUNT + PAGE when there is no ambient transaction.
  • Ambient transactions are not nested; the hint is ignored.
  • The SQL Server session is explicitly restored to READ COMMITTED.
  • Restoration also occurs after exceptions and cancellation.
  • Dapper applies the isolation level for the operation and restores it afterward when the connection remains open.
  • No WITH (NOLOCK), UPDLOCK, or arbitrary raw hint strings are generated.

For PostgreSQL and SQLite, ReadUncommitted is a no-op.

Validation

Pagination v1.0 was validated across:

  • .NET 8 / 9 / 10
  • Core pagination tests
  • EF Core SQLite execution tests
  • Dapper SQL-generation and execution tests
  • SQL Server QueryHint integration tests using Aspire
  • PostgreSQL QueryHint no-op integration test
  • FeatureFusion PostgreSQL integration tests
  • Cancellation and cancellation-after-command-start
  • Sort-column mutation scenarios
  • Nullable-string ordering
  • Forward and backward pagination
  • Cursor validation
  • COUNT + PAGE behavior
  • EF Core and Dapper consistency

The SQL Server integration suite verifies isolation cleanup on an already-open connection after successful execution, exceptions, and cancellation.

What's Changed

  • Finalize BuildingBlocks.Pagination v1.0.0
  • Add typed keyset/cursor pagination for EF Core
  • Add forward and backward cursor navigation
  • Add composite sort keys and recommended keyset indexes
  • Add optional COUNT + PAGE support
  • Add cancellation support
  • Add in-repository Dapper adapter
  • Add SQL Server QueryHint support with isolation cleanup
  • Expand provider and integration test coverage
  • Add 10M / 100M large-dataset performance probes
  • Add FeatureFusion PostgreSQL pagination showcase
  • Improve package and repository documentation

Documentation

  • PACKAGE_README.md
  • docs/building-blocks/pagination.md
  • docs/adr/0003-pagination-keyset.md
  • docs/building-blocks/PAGINATION_TEST_MATRIX.md

Full Changelog:
https://github.com/Maxofpower/FeatureFusion/commits/pagination-v1.0.0

Compare:
...pagination-v1.0.0

BuildingBlocks.Telemetry 1.0.2

Choose a tag to compare

@Maxofpower Maxofpower released this 29 Aug 10:24
b44b829

Config-driven OpenTelemetry metrics, logging, and tracing for .NET 8 / 9 / 10. One AddTelemetry call: stable ASP.NET Core, HttpClient, Runtime, and Npgsql instrumentations, source-only Mediator / MCP / EventBus / MassTransit, telemetry.component span tags, and OTLP (env fast-path), Console, or Azure Monitor. No prerelease OpenTelemetry dependencies.

What's Changed

IntegrateMcp (default false) registers ActivitySource BuildingBlocks.Mcp so MCP spans export with the rest of the host
TelemetryDefaults.McpActivitySource and TelemetryComponentTags.Mcp for filtering (telemetry.component = mcp)

Full Changelog: telemetry-v1.0.1...telemetry-v1.0.2

BuildingBlocks.Mcp 1.0.0

Choose a tag to compare

@Maxofpower Maxofpower released this 29 Aug 10:26
b44b829

Map application message types and public static Minimal API methods to MCP tools on the official C# SDK (ModelContextProtocol 2.2.0) for .NET 8 / 9 / 10. Deny-by-default catalog ([McpTool] or MapTool), typed McpResult, HTTP by default (stdio opt-in), inputSchema from CLR, structuredContent, command-only UseMemoryIdempotency, analyzers BBMCP001–005. Does not require BuildingBlocks.Mediator.

What's Changed

[McpTool] on message types or public static Minimal API methods, deny-by-default scan, or MapTool (including a scoped IServiceProvider overload)
WithMcp() on RouteHandlerBuilder so the same MapGet/MapPost method is also a tool (MVC controllers unsupported)
HTTP MapBuildingBlocksMcp plus opt-in stdio; typed McpResult / McpError
inputSchema from CLR (optional defaults/nullable, enums, [Description] / Swagger text)
Successful CallTool returns JSON text and structuredContent
UseMemoryIdempotency: commands/POST/PUT only; idempotencyKey in schema (format: uuid hint); namespaced keys, lock, JsonElement replay; IMcpIdempotencyStore for Redis
Safe-tool hooks: confirmation, timeout, IMcpToolFilter, IMcpRateLimiter, catalog://tools
Analyzers BBMCP001–005 in the NuGet
Opt-in ActivitySource BuildingBlocks.Mcp (export with Telemetry IntegrateMcp)

Full Changelog: https://github.com/Maxofpower/FeatureFusion/commits/mcp-v1.0.0

What's Changed

Full Changelog: mediator-v1.1.0...mcp-v1.0.0

BuildingBlocks.Telemetry 1.0.1

Choose a tag to compare

@Maxofpower Maxofpower released this 27 Aug 22:29
885a27f

IntegrateMediator also AddMeter so BuildingBlocks.Mediator 1.1.0 Send metrics export with traces.

What's Changed

  • feat(mediator): add typed command/query pipelines and Send metrics by @Maxofpower

Full Changelog: telemetry-v1.0.0...telemetry-v1.0.1

What's Changed

  • feat(mediator): add typed command/query pipelines and Send metrics by @Maxofpower in #17

Full Changelog: telemetry-v1.0.0...telemetry-v1.0.1

BuildingBlocks.Telemetry 1.0.0

Choose a tag to compare

@github-actions github-actions released this 27 Aug 10:04

Config-driven OpenTelemetry metrics, logging, and tracing for .NET 8 / 9 / 10. One AddTelemetry call: stable ASP.NET Core, HttpClient, Runtime, and Npgsql instrumentations, source-only Mediator / EventBus / MassTransit, telemetry.component span tags, and OTLP (env fast-path), Console, or Azure Monitor. No prerelease OpenTelemetry dependencies.

What's Changed

  • feat(telemetry): add Telemetry and SigNoz hosting building blocks by @Maxofpower in #15
  • feat(telemetry): telemetry release pipeline update by @Maxofpower in #16

Full Changelog: https://github.com/Maxofpower/FeatureFusion/commits/telemetry-v1.0.0

BuildingBlocks.Aspire.Hosting.SigNoz 1.0.0

Choose a tag to compare

@Maxofpower Maxofpower released this 27 Aug 09:39
5495de0

What's Changed

  • feat(telemetry): add Telemetry and SigNoz hosting building blocks by @Maxofpower in #15
  • feat(telemetry): telemetry release pipeline update by @Maxofpower in #16

Full Changelog: mediator-v1.0.1...signoz-v1.0.0

BuildingBlocks.Mediator 1.1.0

Choose a tag to compare

@Maxofpower Maxofpower released this 27 Aug 22:23
885a27f

Add compile-time command vs query pipeline behaviors, fail-fast open-generic registration, and opt-in Send metrics on UseTelemetry. 1.0.1 filter bases stay unchanged. Hosts that use BuildingBlocks.Telemetry should take 1.0.1 so IntegrateMediator registers the meter.

What's Changed

  • feat(mediator): add typed command/query pipelines and Send metrics by @Maxofpower

Full Changelog: mediator-v1.0.1...mediator-v1.1.0

BuildingBlocks.Mediator 1.0.1

Choose a tag to compare

@Maxofpower Maxofpower released this 10 Aug 17:29
1ee7af9

Multi-target net8/net9/net10 for v1.0.1
Expand BuildingBlocks.Mediator beyond net10-only, refresh the NuGet description, and run the full test suite on each TFM in CI.

What's Changed

  • feat(mediator): extract BuildingBlocks.Mediator NuGet package by @Maxofpower in #13
  • release(mediator): multi-target net8/net9/net10 for v1.0.1 by @Maxofpower in #14

Full Changelog: mediator-v1.0.0...mediator-v1.0.1

BuildingBlocks.Mediator 1.0.0

Choose a tag to compare

@Maxofpower Maxofpower released this 10 Aug 00:10
b22bc80

BuildingBlocks.Mediator 1.0.0

CQRS-first mediator for .NET 10: ICommand / IQuery, ordered pipeline behaviors, opt-in telemetry, startup validation, configurable handler lifetime, and open-generic handlers.

Highlights

  • AddMediator with assembly scanning (no Scrutor)
  • Ordered AddOpenBehavior
  • UseTelemetry, ValidateOnStartup
  • HandlerLifetime (Transient / Scoped / Singleton)
  • Open-generic handlers closed on demand
  • Roslyn analyzers BBM001 / BBM002

Install

dotnet add package BuildingBlocks.Mediator --version 1.0.0