Kanject.Core.Annotations 3.12.7

Prefix Reserved
There is a newer version of this package available.
See the version list below for details.
dotnet add package Kanject.Core.Annotations --version 3.12.7
                    
NuGet\Install-Package Kanject.Core.Annotations -Version 3.12.7
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Kanject.Core.Annotations" Version="3.12.7" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Kanject.Core.Annotations" Version="3.12.7" />
                    
Directory.Packages.props
<PackageReference Include="Kanject.Core.Annotations" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Kanject.Core.Annotations --version 3.12.7
                    
#r "nuget: Kanject.Core.Annotations, 3.12.7"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Kanject.Core.Annotations@3.12.7
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Kanject.Core.Annotations&version=3.12.7
                    
Install as a Cake Addin
#tool nuget:?package=Kanject.Core.Annotations&version=3.12.7
                    
Install as a Cake Tool

Kanject.Core.Annotations

Roslyn incremental source generators and analyzers for the attribute-driven features of Kanject.Core: [Parallel] fan-out, [Recurring] / [RecurringHosted] schedules, [QueryableEnum] lookups, and the opt-in PrintInConsole interceptors. The generators turn attributes into ordinary C# at compile time, so these features use no runtime reflection. The analyzers catch invalid attribute usage in the editor, before the generator would otherwise produce nothing or broken code.

Kanject.Core depends on this package, so its generators normally reach your project through Kanject.Core. Reference it explicitly anyway, on the same version as Kanject.Core, so the generator version is pinned alongside the runtime.

Installation

<ItemGroup>
  <PackageReference Include="Kanject.Core" />                                    
  <PackageReference Include="Kanject.Core.Annotations" PrivateAssets="all" />   
</ItemGroup>

Or from the CLI: dotnet add package Kanject.Core.Annotations, then add PrivateAssets="all" to the new reference. Keep its version equal to your Kanject.Core version, because the generated code calls into Kanject.Core's runtime types.

You need this package for the following:

  • [Parallel] generated overloads
  • [Recurring] / [RecurringHosted] generated loops, services and registrations
  • [QueryableEnum] on your own enums
  • the PrintInConsole interceptors and the MSBuild properties
  • every diagnostic in the table below

You don't need it for the parts of Kanject.Core you call directly, such as ParallelLoop, RecurringLoop, the timezone, JSON and collection helpers, or plain PrintInConsole.

Package layout. This is not a development-dependency package. It ships the generators in analyzers/dotnet/cs, a lib/netstandard2.0 assembly, MSBuild props and targets in build/ and buildTransitive/, and a dependency on Kanject.Core.Annotations.Attributes (the attribute types). PrivateAssets="all" stops the generators from also running in projects that reference yours.

dotnet add package writes a plain reference for this package, with no IncludeAssets line. If you add an IncludeAssets line yourself, make sure it includes compile. The attribute types from Kanject.Core.Annotations.Attributes reach your project through this package, and an IncludeAssets list without compile strips them from compilation.

The analyzer assembly targets netstandard2.0, as Roslyn requires. The generated code calls into Kanject.Core and targets the same frameworks: .NET 8, .NET 9 and .NET 10.

Quick start

using Kanject.Core.Annotations.Attributes.Recurring;
using Kanject.Core.Annotations.Attributes.Recurring.Enums;

namespace Shop;

public sealed partial class HeartbeatService(IPingClient client)
{
    [Recurring(5, RecurringRateUnit.Seconds, MaxIterations = 12)]
    public Task PingAsync(CancellationToken ct) => client.PingAsync(ct);
}

At compile time, RecurringGenerator emits HeartbeatServiceRecurringExtensions.PingAsyncRecurringAsync(...), a partial IHeartbeatServiceRecurring interface, and a partial declaration of HeartbeatService that implements it. Callers write await heartbeat.PingAsyncRecurringAsync(cancellationToken: ct). If the method returned an unsupported type, or were async void, the analyzer would report KANREC001 or KANREC012 instead of leaving you with no extension method.

What it generates

Generator Triggered by Emits
ParallelGenerator [Parallel] on a method {Type}ParallelExtensions with {Method}ParallelAsync (over ReadOnlyMemory<T>, T[], IReadOnlyList<T>, IEnumerable<T>, IAsyncEnumerable<T>), {Method}ParallelStream (chunk methods that return a value), and {Method}ParallelOutcomesAsync (per-item methods that return a value); plus a partial I{Type}Parallel interface and a partial class that implements it
RecurringGenerator [Recurring] on a method {Type}RecurringExtensions with {Method}RecurringAsync, plus {Method}RecurringStream and {Method}RecurringToLastAsync for methods that return a value; plus a partial I{Type}Recurring interface and a partial class that implements it
RecurringHostedGenerator [RecurringHosted] together with [Recurring] {Type}{Method}RecurringHostedService : BackgroundService and {Type}RecurringHostedExtensions.Add{Type}{Method}Recurring(...) with overloads taking nothing, an Action<RecurringOptions>, or an IConfiguration
QueryableEnumGenerator [QueryableEnum] on an enum A {Enum}Info record struct and a static {Enum}Query class: name/description/display-name lookups, Get{Parameter} accessors for each [EnumParameter], parsing and search helpers, and one nested const string class per entry in ConstantParameters
PrintInConsoleInterceptorGenerator <EnablePrintInConsoleInterceptor>true</EnablePrintInConsoleInterceptor> C# interceptors for every PrintInConsole call. Each one carries a severity inferred at compile time and routes through ConsolePrintInterceptorProvider

Generated member names append a fixed suffix to the method name. [Parallel] drops a trailing Async first (ProcessAsync becomes ProcessParallelAsync). [Recurring] keeps the name as written (PingAsync becomes PingAsyncRecurringAsync, and AddHeartbeatServicePingAsyncRecurring for hosted registration).

Things to know when annotating code:

  • Instance methods need a partial containing type. The Parallel and Recurring generators add a partial declaration of the same kind (class, record or struct) to the containing type so it implements the generated interface. The generated extension class and interface are internal when the containing type isn't public. KANPAR011 ([Parallel]) and KANREC013 ([Recurring]) report a missing partial.
  • [QueryableEnum] output follows the enum. It is emitted into the enum's namespace (or the global namespace) and names the enum by its fully qualified name, so nested enums work. It is internal when the enum isn't public. A private or protected nested enum can't be reached from the generated top-level types and reports KANQE001. Aliased members (A = 1, B = 1) share one value entry, owned by the first-declared name.
  • Some shapes are not generated. Generic methods (KANPAR006, KANREC004) and methods on nested types (KANPAR007, KANREC003) get a warning instead of generated code. ref/out/in parameters are errors (KANPAR008, KANREC008).
  • [ParallelHosted] is validated but not generated. The analyzer checks it (KANPAR009, KANPAR010) and reports KANPAR014 because this release emits no hosting code for it.

MSBuild properties

Set these in the project file of a project that references this package. The package exposes them to the generators and analyzers as CompilerVisibleProperty items.

Property Default Effect
EnablePrintInConsoleInterceptor off Emits the PrintInConsole interceptors and adds Kanject.Core.SystemConsole.Interceptors to InterceptorsNamespaces / InterceptorsPreviewNamespaces
EnableParallelGenerator on false disables [Parallel] generation
EnableRecurringGenerator on false disables [Recurring] generation
EnableRecurringHostedGenerator on false disables [RecurringHosted] generation while keeping [Recurring]
EnableKanjectDevAnalyzers off Turns on the file-organization analyzers KANDEV001-KANDEV005 (see below)
KanjectDeterministicCode off Turns on the determinism analyzer KANDEV006

Opt-in convention analyzers

The package also contains optional analyzers for a strict file-organization convention: one top-level type per file, no accessible nested types, and enums kept under an Enums/ folder. They report nothing unless you opt in:

<PropertyGroup>
  <EnableKanjectDevAnalyzers>true</EnableKanjectDevAnalyzers>
  
  <KanjectDeterministicCode>true</KanjectDeterministicCode>
</PropertyGroup>

Generated code is excluded from these rules. KANDEV005 compares a type's namespace with its folder using the project's RootNamespace and ProjectDir, which the package makes visible to the compiler automatically. KANDEV006 flags ambient time (DateTime.Now/UtcNow/Today, DateTimeOffset.Now/UtcNow), current culture, Environment.TickCount and unseeded Random. Guid.NewGuid() and new Random(seed) are allowed. To change a rule's severity, use .editorconfig:

[*.cs]
dotnet_diagnostic.KANDEV001.severity = warning

Diagnostics

ID Severity What it means
KANPAR001 Error [Parallel] method has no partition parameter (a single T or a chunk such as ReadOnlyMemory<T>)
KANPAR002 Error MaxDegreeOfParallelism is negative
KANPAR003 Error ChunkSize is negative
KANPAR004 Warning ChunkSize is set but ChunkingMode is EvenSplit, so it is ignored
KANPAR005 Warning RetryBackoffMs is set but RetryCount is 0
KANPAR006 Warning [Parallel] on a generic method is not generated
KANPAR007 Warning [Parallel] on a method of a nested type is not generated
KANPAR008 Error [Parallel] method has a ref/out/in parameter
KANPAR009 Error [ParallelHosted] without [Parallel] on the same method
KANPAR010 Warning [ParallelHosted(Lifetime = Scoped)] on a static method has no effect
KANPAR011 Error Type containing an instance [Parallel] method is not partial
KANPAR012 Error [Parallel] return type is not void, T, Task, Task<T>, ValueTask or ValueTask<T>
KANPAR013 Info Chunk parameter type makes each partition allocate an array; prefer ReadOnlyMemory<T>
KANPAR014 Warning [ParallelHosted] generates no hosting code in this release, so it has no effect
KANPAR050 Warning async void lambda passed to Parallel.For / ForEach / Invoke; the loop won't await it
KANREC001 Error [Recurring] return type is not supported
KANREC002 Error [Recurring] rate value is not greater than zero
KANREC003 Warning [Recurring] on a method of a nested type is not generated
KANREC004 Warning [Recurring] on a generic method is not generated
KANREC005 Warning MaxJitterMs is negative (treated as zero)
KANREC006 Warning MaxDurationSeconds is negative (treated as no limit)
KANREC007 Warning MaxIterations is negative (treated as no limit)
KANREC008 Error [Recurring] method has a ref/out/in parameter
KANREC009 Error [RecurringHosted] without [Recurring] on the same method
KANREC010 Warning [RecurringHosted(Lifetime = Scoped)] on a static method has no effect
KANREC011 Error [RecurringHosted] method takes parameters other than a single CancellationToken
KANREC012 Warning [Recurring] on an async void method; completion and exceptions can't be observed
KANREC013 Error Type containing an instance [Recurring] method is not partial
KANQE001 Error A [QueryableEnum] enum is private or protected (or nested in such a type), so the generated types can't reference it
KAN001 Warning A ConstantParameters entry has more than one value on an enum member, so no constant is generated
KAN002 Error The same [EnumParameter] name appears more than once on one enum member
KANJECT0021 Error A constant parameter value can't be turned into a valid C# identifier
KANJECT0022 Error A constant parameter value is empty or whitespace
KANJECT0023 Error Two constant parameter values produce the same identifier
KANJECT0024 Error A ConstantParameters name doesn't exist on any enum member
KANPIC001 Info Shows the severity the PrintInConsole interceptor inferred for a call site
KANDEV001 Error File declares more than one top-level type (opt-in)
KANDEV002 Error Public/internal/protected nested type declaration (opt-in)
KANDEV003 Error Enum outside an Enums/ folder (opt-in)
KANDEV004 Error File not named after the type it declares (opt-in)
KANDEV005 Warning Namespace doesn't match the folder path (opt-in)
KANDEV006 Warning Ambient nondeterministic API in code marked deterministic (opt-in)
KANJECTGEN001 Error A generator hit an unhandled exception; the message carries the exception text

A code fix accompanies KAN001, KAN002 and KANJECT0021-KANJECT0024. It can keep only the first value, remove a duplicate [EnumParameter], or remove the offending name from ConstantParameters.

Package Role Availability
Kanject.Core Runtime library the generated code calls into; reference it alongside this package nuget.org
Kanject.Core.Annotations.Attributes The attribute types these generators read (a dependency of this package) nuget.org

License

Licensed under the Kanject Code Libraries License Agreement (KCLLA); the full text ships in this package as LICENSE.md. Organizations whose trailing-twelve-month gross revenue and total funding raised are each below US$250,000 may use it at no cost under the Free Tier. At or above either threshold a commercial license is required — contact commercial@kanjectbusiness.com.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (6)

Showing the top 5 NuGet packages that depend on Kanject.Core.Annotations:

Package Downloads
Kanject.Core

Kanject SDK core library

Kanject.Core.Adapter.Annotations

Kanject Adapter Annotations — Source generator for service adapter endpoint, auth, and OAuth lifecycle codegen

Kanject.Core.CloudFunction.Aws.Annotations

Source generator + analyzers that eliminate Lambda host boilerplate (the `Functions.Configuration.cs` file) for projects built on Kanject.Core.CloudFunction.Provider.AwsLambda. Pair with the `[CloudFunctionHost]` attribute shipped in Kanject.Core.CloudFunction.Abstractions.

Kanject.Core.Queue.Provider.AwsSqs.Annotations

Kanject Core Queue AWS Sqs Annotations

Kanject.Core.Api.Annotations

Kanject Core Api Annotations

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
3.14.0 58 10/2/2026
3.13.1 543 9/27/2026
3.13.0 479 9/27/2026
3.12.7 489 9/26/2026
3.12.6 559 9/7/2026
3.12.5 488 8/27/2026
3.12.4 620 8/22/2026
3.12.3 543 8/10/2026
3.12.2 526 8/9/2026
3.12.1 561 8/5/2026
3.12.0 573 8/5/2026
3.11.0 626 8/3/2026
3.10.6 611 7/30/2026
3.10.5 655 7/18/2026
3.10.4 149 7/13/2026
3.10.3 391 7/11/2026
3.10.2 465 7/11/2026
3.10.0 2,317 7/9/2026