Feature — Specification Extension Code Generator
Title: Compile-Time Named Repository Extensions from Specification Classes
Intent
"Eliminate the boilerplate of wiring specification classes to repository calls by generating named, strongly-typed extension methods at compile time — so ActiveCustomerSpecification automatically produces repository.FindAllActiveCustomersAsync()."
The Problem Today
The v1.7.0 specification pattern lets teams write repository.FindAllAsync(new ActiveCustomerSpec()), which is already an improvement over inline filters. However, calling code still constructs the specification object explicitly at every call site. For frequently-used specifications, teams naturally want a shorthand — but writing and maintaining FindAllActiveCustomersAsync() extension methods by hand for every specification is repetitive and drifts over time.
What We Are Building
- A
[GenerateRepositoryExtensions] attribute that can be placed on any class implementing ISpecification<TEntity>
- A Roslyn incremental source generator that detects decorated specification classes and emits a static extension class targeting
IRepository<TEntity> (and optionally EntityManager<TEntity, TKey>)
- Generated method names derived from the specification class name:
ActiveCustomerSpecification → FindAllActiveCustomersAsync(), FindFirstActiveCustomerAsync(), CountActiveCustomersAsync(), ExistsActiveCustomerAsync()
- Each generated method internally calls
new ActiveCustomerSpecification().ToQuery() and delegates to the corresponding repository method
- The generator ships in the
Kista.SourceGenerators package alongside the repository scaffolding generator from the previous feature
- Generated code is transparent, visible in IDE navigation, and fully overridable — consumers can always fall back to the generic API
Benefits
- Frequently-used specifications get a one-line call site:
await repository.FindAllActiveCustomersAsync()
- No hand-written extension methods to maintain — the source of truth is the specification class itself
- Consistent naming convention across the entire codebase
- Opt-in per specification: only classes with the attribute trigger generation
- Complements the repository scaffolding generator — both ship in the same package
See the ROADMAP for the full feature description and context.
Feature — Specification Extension Code Generator
Title: Compile-Time Named Repository Extensions from Specification Classes
Intent
The Problem Today
The v1.7.0 specification pattern lets teams write
repository.FindAllAsync(new ActiveCustomerSpec()), which is already an improvement over inline filters. However, calling code still constructs the specification object explicitly at every call site. For frequently-used specifications, teams naturally want a shorthand — but writing and maintainingFindAllActiveCustomersAsync()extension methods by hand for every specification is repetitive and drifts over time.What We Are Building
[GenerateRepositoryExtensions]attribute that can be placed on any class implementingISpecification<TEntity>IRepository<TEntity>(and optionallyEntityManager<TEntity, TKey>)ActiveCustomerSpecification→FindAllActiveCustomersAsync(),FindFirstActiveCustomerAsync(),CountActiveCustomersAsync(),ExistsActiveCustomerAsync()new ActiveCustomerSpecification().ToQuery()and delegates to the corresponding repository methodKista.SourceGeneratorspackage alongside the repository scaffolding generator from the previous featureBenefits
await repository.FindAllActiveCustomersAsync()See the ROADMAP for the full feature description and context.