Kanject.Core.CloudFunction.Aws.Annotations 1.7.0

Prefix Reserved
dotnet add package Kanject.Core.CloudFunction.Aws.Annotations --version 1.7.0
                    
NuGet\Install-Package Kanject.Core.CloudFunction.Aws.Annotations -Version 1.7.0
                    
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.CloudFunction.Aws.Annotations" Version="1.7.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Kanject.Core.CloudFunction.Aws.Annotations" Version="1.7.0" />
                    
Directory.Packages.props
<PackageReference Include="Kanject.Core.CloudFunction.Aws.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.CloudFunction.Aws.Annotations --version 1.7.0
                    
#r "nuget: Kanject.Core.CloudFunction.Aws.Annotations, 1.7.0"
                    
#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.CloudFunction.Aws.Annotations@1.7.0
                    
#: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.CloudFunction.Aws.Annotations&version=1.7.0
                    
Install as a Cake Addin
#tool nuget:?package=Kanject.Core.CloudFunction.Aws.Annotations&version=1.7.0
                    
Install as a Cake Tool

Kanject.Core.CloudFunction.Aws.Annotations

A Roslyn source generator, with analyzers and code fixes, that removes the hand-written plumbing from AWS Lambda hosts built on Kanject.Core.CloudFunction.Provider.AwsLambda. You mark a partial class with [CloudFunctionHost] and write ConfigureServices. The generator emits everything else: the base class, the constructor, OnStartup, the assembly-level Lambda serializer, and bind-or-throw checks for required configuration sections.

Installation

<ItemGroup>
  <PackageReference Include="Kanject.Core.CloudFunction.Provider.AwsLambda" />                  
  <PackageReference Include="Kanject.Core.CloudFunction.Aws.Annotations" PrivateAssets="all" />
  <PackageReference Include="Amazon.Lambda.Serialization.SystemTextJson" />                     
</ItemGroup>

If you don't use central package management, add Version="x.y.z" to each reference. From the command line:

dotnet add package Kanject.Core.CloudFunction.Aws.Annotations

Things to know about how this package is wired:

  • Reference it directly. Kanject.Core.CloudFunction.Provider.AwsLambda depends on this package, so the generator can also reach your project transitively. Reference it yourself anyway, so the generator version is explicit and doesn't depend on how NuGet resolves the provider's dependency.
  • Add PrivateAssets="all" yourself. The package is not marked as a development dependency, so dotnet add package writes a plain reference. PrivateAssets="all" stops the generator from flowing to projects that reference yours.
  • There is no separate .Attributes package. [CloudFunctionHost] and [RequireConfigSection<T>] live in Kanject.Core.CloudFunction.Abstractions, which comes with the provider.
  • The generated code needs the provider. It derives from the provider's CloudFunction. By default it also references Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer. With ConfigurationSource.AwsSystemManagerParameterStore, also reference Kanject.Core.Api.Aws.Extensions.
  • Frameworks and compiler. The package targets netstandard2.0 because it runs inside the compiler. Use it from projects that target .NET 8, .NET 9 or .NET 10 (the provider's frameworks). It is built against Roslyn 5.6 (Microsoft.CodeAnalysis.CSharp 5.6.0), so build with an SDK whose compiler is at least that version. An older compiler skips the generator and reports CS9057.
  • MSBuild default. The package's props set EnableConfigurationBindingGenerator to true for .NET 8+ projects unless you've already set it, so the generated Get<T>() calls bind without reflection. Set it to false in your project to opt out.

Quick start

Before: a hand-written host.

using Amazon.Lambda.Core;
using Kanject.Core.Api.Aws.Extensions.Vault.ParameterStore;
using Kanject.Core.CloudFunction.Abstractions.Enums;
using Kanject.Core.CloudFunction.Provider.AwsLambda;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace Orders.Lambda;

public partial class Functions : CloudFunction
{
#if DEBUG
    public Functions() : base(CloudFunctionEnvironment.Development) { }
#else
    public Functions() : base() { }
#endif

    public override void OnStartup(IConfigurationBuilder configurationBuilder)
    {
#if DEBUG
        configurationBuilder.AddAwsSystemManagerParameterStore(fetchSecretPathFromAppSettings: true);
#else
        configurationBuilder.AddAwsSystemManagerParameterStore();
#endif
    }

    public override void ConfigureServices(IServiceCollection services)
    {
        var appSettings = Configuration.GetSection("AppSettings").Get<AppSettings>()
                          ?? throw new InvalidOperationException("'AppSettings' is required.");

        services.AddSingleton(appSettings);
        services.AddScoped<OrderService>();
    }

    public override void Configure(IServiceProvider serviceProvider) { }
}

After: the same host with the generator. AppSettings and OrderService are your own types.

using Kanject.Core.CloudFunction.Abstractions.Attributes;
using Kanject.Core.CloudFunction.Abstractions.Enums;
using Microsoft.Extensions.DependencyInjection;

namespace Orders.Lambda;

[CloudFunctionHost(
    DebugEnvironment = CloudFunctionEnvironment.Development,
    ConfigurationSource = ConfigurationSource.AwsSystemManagerParameterStore)]
[RequireConfigSection<AppSettings>("AppSettings")]
public partial class Functions
{
    public override void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton(AppSettings);   // generated property, already bound and validated
        services.AddScoped<OrderService>();
    }
}

Your Lambda handler methods stay where they were, in other partial files of the same class. The Kanject.Core.CloudFunction.Provider.AwsLambda package covers handlers, scopes and runtime behavior.

What gets generated

For each [CloudFunctionHost] class, the generator adds one file, {ClassName}.CloudFunctionHost.g.cs. The following is what it emits for the "after" example in a Debug build (license header, #nullable enable and doc comments omitted):

// <auto-generated/>
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Kanject.Core.CloudFunction.Abstractions.Enums;
using Kanject.Core.CloudFunction.Provider.AwsLambda;
using Kanject.Core.Api.Aws.Extensions.Vault.ParameterStore;

[assembly: global::Amazon.Lambda.Core.LambdaSerializerAttribute(typeof(global::Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace Orders.Lambda;

partial class Functions : global::Kanject.Core.CloudFunction.Provider.AwsLambda.CloudFunction
{
    public Functions() : base(global::Kanject.Core.CloudFunction.Abstractions.Enums.CloudFunctionEnvironment.Development) { }

    public global::Orders.Lambda.AppSettings AppSettings { get; private set; } = null!;

    public override void OnStartup(global::Microsoft.Extensions.Configuration.IConfigurationBuilder configurationBuilder)
    {
        configurationBuilder.AddAwsSystemManagerParameterStore(fetchSecretPathFromAppSettings: true);
        AddAdditionalConfigurationSources(configurationBuilder);

        var validationConfiguration = configurationBuilder.Build();
        AppSettings = validationConfiguration.GetSection("AppSettings").Get<global::Orders.Lambda.AppSettings>()
            ?? throw new global::System.InvalidOperationException("Required configuration section 'AppSettings' is missing or could not bind to global::Orders.Lambda.AppSettings.");
    }

    partial void AddAdditionalConfigurationSources(global::Microsoft.Extensions.Configuration.IConfigurationBuilder configurationBuilder);

    protected override void ConfigureLogging(global::Microsoft.Extensions.Logging.ILoggingBuilder logging)
    {
        AddAdditionalLoggingProviders(logging);
    }

    partial void AddAdditionalLoggingProviders(global::Microsoft.Extensions.Logging.ILoggingBuilder logging);
}

The generator reads the compilation's DEBUG symbol and writes only the matching branch, so the output contains no #if directives. A Release build of the same class emits public Functions() : base() { } and configurationBuilder.AddAwsSystemManagerParameterStore();. Deploy Release builds: a Debug build bakes DebugEnvironment into the constructor.

In Release, the Kanject.Core.Api.Aws.Extensions Parameter Store source reads the parameter path from the SECRET_PARAMETER_PATHNAME environment variable. In Debug with DebugFetchSecretPathFromAppSettings (the default), it reads AppSettings:SecretParameterPathName, AppSettings:AwsRegion and AppSettings:AwsProfile from the configuration built so far.

[CloudFunctionHost] options

Property Default Effect on the generated code
DebugEnvironment not set In Debug builds, the constructor passes this CloudFunctionEnvironment to the base. If you leave it unset, both configurations use base(), and the environment comes from ASPNETCORE_LAMBDA_ENVIRONMENT / ASPNETCORE_ENVIRONMENT.
ConfigurationSource None AwsSystemManagerParameterStore adds configurationBuilder.AddAwsSystemManagerParameterStore(...) to OnStartup.
DebugFetchSecretPathFromAppSettings true With Parameter Store, Debug builds call the fetchSecretPathFromAppSettings: true overload. Set it to false to emit the parameterless call in both configurations.
EmitLambdaSerializer true Emits [assembly: LambdaSerializer(typeof(DefaultLambdaJsonSerializer))]. Set it to false if the project declares its own serializer.
EnableAot false Derives from Kanject.Core.CloudFunction.Provider.AwsLambda.Aot.CloudFunction instead of the default host.
Provider AwsLambda The only supported value.

Required configuration sections

Each [RequireConfigSection<T>("Section")] adds two things:

  • A bind-or-throw check at the end of OnStartup. It runs after the attribute-driven sources and your AddAdditionalConfigurationSources hook. If the section is missing, or doesn't bind to T, the cold start fails with InvalidOperationException and names the section.
  • A public property holding the bound instance. The property exists by the time ConfigureServices runs. The generator names it from PropertyName if you set it, otherwise from the section name if that is a valid C# identifier, otherwise from T's simple name. If an explicit PropertyName is not a valid identifier, the check still runs but no property is emitted.
[CloudFunctionHost]
[RequireConfigSection<AppSettings>("AppSettings")]                                  // property: AppSettings
[RequireConfigSection<QueueSettings>("Queues:Orders", PropertyName = "OrderQueue")] // property: OrderQueue
public partial class Functions { /* ... */ }

T can be a class or a struct. For a class (or a nullable struct such as int?) the property is initialised with null!, and validation throws when the section is missing or binds to null. A non-nullable struct can't be null, so its property starts at default and validation throws when the section doesn't exist. The validation builds the configuration one extra time per cold start. It does not register IOptions<T>; call services.Configure<T>(...) in ConfigureServices if you want options binding too. If two attributes resolve to the same property name, you get a duplicate-member compile error. Set PropertyName on one of them to fix it.

Extension points

The generator owns OnStartup and ConfigureLogging, and it declares two optional partial-method hooks for you to implement. If you leave a hook unimplemented, the compiler removes its call.

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace Orders.Lambda;

public partial class Functions
{
    // Runs at the end of the generated OnStartup, after the attribute-driven sources and before
    // [RequireConfigSection] validation.
    partial void AddAdditionalConfigurationSources(IConfigurationBuilder configurationBuilder)
    {
        configurationBuilder.AddJsonFile("features.json", optional: true);
    }

    // Runs after the base host's ClearProviders() + AddConsole().
    partial void AddAdditionalLoggingProviders(ILoggingBuilder logging)
    {
        logging.SetMinimumLevel(LogLevel.Information);
    }
}

Configure(IServiceProvider) remains yours to override for post-container work. If you need full control of OnStartup, remove the attribute and write the host by hand (KANCF003 enforces this).

Migrating an existing host

The migration analyzer reports KANCF100 (Info) on a hand-written host that the generator can replace. The code fix, Migrate to [CloudFunctionHost], rewrites it. The analyzer only fires when all of these are true:

  • the class derives directly from Kanject.Core.CloudFunction.Provider.AwsLambda.CloudFunction, is partial, is not abstract, and doesn't already carry the attribute;
  • every declared constructor is parameterless and calls base() or base(CloudFunctionEnvironment.X);
  • OnStartup is empty or contains exactly one AddAwsSystemManagerParameterStore(...) call;
  • Configure(IServiceProvider) is absent or empty, and ConfigureServices is overridden;
  • the assembly declares [assembly: LambdaSerializer(typeof(DefaultLambdaJsonSerializer))].

The fix does the following:

  • Adds [CloudFunctionHost(...)], inferring DebugEnvironment from the constructor and ConfigurationSource from OnStartup.
  • Removes the constructors, OnStartup, the empty Configure and the : CloudFunction base.
  • Removes the LambdaSerializer assembly attribute when it is in the same file.
  • Keeps ConfigureServices exactly as written.

Afterwards, check these by hand:

  • Run the fix in a Debug configuration so it can see a constructor behind #if DEBUG.
  • If your old Debug branch called AddAwsSystemManagerParameterStore() without arguments, add DebugFetchSecretPathFromAppSettings = false. The fix leaves that property at its default of true.
  • Remove a LambdaSerializer attribute that lives in another file, and any usings that are now unused.

Native AOT

EnableAot = true only selects the AOT-oriented host base class. The functions you register in ConfigureServices must be AOT-safe as well. DefaultLambdaJsonSerializer uses reflection-based System.Text.Json, so for an AOT function set EmitLambdaSerializer = false and declare your own source-generated serializer, such as SourceGeneratorLambdaJsonSerializer<TContext> from Amazon.Lambda.Serialization.SystemTextJson.

Diagnostics

ID Severity What it means
KANCF001 Error The [CloudFunctionHost] class is not partial (code fix: Make class partial).
KANCF003 Error The class declares its own OnStartup override, which the generator owns. Use AddAdditionalConfigurationSources, change ConfigurationSource, or drop the attribute.
KANCF004 Error More than one [CloudFunctionHost] class exists in the assembly (the Lambda serializer attribute is assembly-wide).
KANCF100 Info A hand-written host matches the migration shape (code fix: Migrate to [CloudFunctionHost]).

There is no KANCF002. If the class declares a base type other than CloudFunction, the compiler rejects it, because the generated partial fixes the base class.

Package Role Availability
Kanject.Core.CloudFunction.Provider.AwsLambda The Lambda host runtime whose CloudFunction base the generated code extends nuget.org
Kanject.Core.CloudFunction.Abstractions Defines [CloudFunctionHost], [RequireConfigSection<T>] and the option enums (arrives with the provider) nuget.org
Kanject.Core.Api.Aws.Extensions Supplies AddAwsSystemManagerParameterStore for ConfigurationSource.AwsSystemManagerParameterStore nuget.org
Kanject.Core.Queue.Provider.AwsSqs SQS queue consumers that you can dispatch from the host's Lambda handlers 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.

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Kanject.Core.CloudFunction.Aws.Annotations:

Package Downloads
Kanject.Core.CloudFunction.Provider.AwsLambda

Kanject core cloud function aws lambda provider

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.7.0 39 10/2/2026
1.6.1 121 9/27/2026
1.6.0 95 9/27/2026
1.5.7 104 9/26/2026
1.5.6 149 9/7/2026
1.5.5 124 8/27/2026
1.5.4 136 8/22/2026
1.5.3 139 8/10/2026
1.5.2 127 8/9/2026
1.5.1 122 8/5/2026
1.5.0 125 8/5/2026
1.4.0 142 8/3/2026
1.3.5 145 7/30/2026
1.3.4 148 7/18/2026
1.3.3 145 7/13/2026
1.3.2 143 7/11/2026
1.3.1 140 7/11/2026
1.3.0 159 7/9/2026
1.2.1 150 7/9/2026