EricksonLopez.Pagination.SourceGenerators
0.0.0-alpha.0
dotnet add package EricksonLopez.Pagination.SourceGenerators --version 0.0.0-alpha.0
NuGet\Install-Package EricksonLopez.Pagination.SourceGenerators -Version 0.0.0-alpha.0
<PackageReference Include="EricksonLopez.Pagination.SourceGenerators" Version="0.0.0-alpha.0" />
<PackageVersion Include="EricksonLopez.Pagination.SourceGenerators" Version="0.0.0-alpha.0" />
<PackageReference Include="EricksonLopez.Pagination.SourceGenerators" />
paket add EricksonLopez.Pagination.SourceGenerators --version 0.0.0-alpha.0
#r "nuget: EricksonLopez.Pagination.SourceGenerators, 0.0.0-alpha.0"
#:package EricksonLopez.Pagination.SourceGenerators@0.0.0-alpha.0
#addin nuget:?package=EricksonLopez.Pagination.SourceGenerators&version=0.0.0-alpha.0&prerelease
#tool nuget:?package=EricksonLopez.Pagination.SourceGenerators&version=0.0.0-alpha.0&prerelease
EricksonLopez.Pagination.SourceGenerators
Roslyn source generator for Native AOT cursor decoders in the EricksonLopez.Pagination ecosystem.
Overview
By default, cursor pagination relies on runtime reflection to dynamically decode strings into strongly typed keys (e.g. string → int). This reflection-based approach is not compatible with Native AOT publishing or aggressive trimming.
This source generator solves that by intercepting calls to ToCursorPagedListAsync at compile time and generating zero-allocation, AOT-friendly parsers for your cursor types.
Installation
Install the package into the project where you execute your queries:
<PackageReference Include="EricksonLopez.Pagination.SourceGenerators" Version="[VERSION]" />
Note: The generator is a development dependency and will not be included as a runtime dependency in your published output.
Usage
1. Let the generator work
Simply write your pagination queries normally. The analyzer will automatically detect which types are being used as cursor keys.
var paged = await dbContext.Users
.Keyset(new CursorPaginationParameters { After = "..." })
.Ascending(u => u.Id) // Id is int
.ToCursorPagedListAsync();
2. Register the decoders
The source generator produces an extension method AddAotCursorDecoders() in the EricksonLopez.Pagination.Generated namespace.
You must call this during your application startup to inject the decoders into the DI container:
using EricksonLopez.Pagination.Generated;
var builder = WebApplication.CreateBuilder(args);
// Register the AOT-safe decoders generated at compile time
builder.Services.AddAotCursorDecoders();
Filter Provider Generation (AOT-Safe Filtering)
Decorate your entity models with [GenerateFilterProvider] to automatically generate compile-time, zero-reflection IFilterProvider<TEntity> implementations for Native AOT:
using EricksonLopez.Pagination.Abstractions;
[GenerateFilterProvider]
public class Product
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public double Price { get; set; }
public bool IsActive { get; set; }
}
The generator emits ProductFilterProvider with a singleton ProductFilterProvider.Instance that translates FilterParameters strings (e.g. "name~=Phone,price<=500") into strongly typed LINQ predicates without runtime reflection:
var filter = FilterParameters.From("name~=Phone,price<=500");
var filteredQuery = dbContext.Products.ApplyFilter(ProductFilterProvider.Instance, filter);
Supported Types for Keyset Cursor Decoders
The source generator automatically provides decoders for:
- Primitives (
int,long,string,DateTime,DateTimeOffset,Guid) - Any
Enum - Any type that implements
IParsable<T>orISpanParsable<T> - Any type with a
Parse(string)orTryParse(string, IFormatProvider, out T)method
If you attempt to paginate by a custom struct that does not meet these criteria, you will receive compile-time warning PAG001.
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.0.0-alpha.0 | 54 | 8/25/2026 |