Kanject.Core.CloudFunction.Provider.AwsLambda
3.8.0
Prefix Reserved
See the version list below for details.
dotnet add package Kanject.Core.CloudFunction.Provider.AwsLambda --version 3.8.0
NuGet\Install-Package Kanject.Core.CloudFunction.Provider.AwsLambda -Version 3.8.0
<PackageReference Include="Kanject.Core.CloudFunction.Provider.AwsLambda" Version="3.8.0" />
<PackageVersion Include="Kanject.Core.CloudFunction.Provider.AwsLambda" Version="3.8.0" />
<PackageReference Include="Kanject.Core.CloudFunction.Provider.AwsLambda" />
paket add Kanject.Core.CloudFunction.Provider.AwsLambda --version 3.8.0
#r "nuget: Kanject.Core.CloudFunction.Provider.AwsLambda, 3.8.0"
#:package Kanject.Core.CloudFunction.Provider.AwsLambda@3.8.0
#addin nuget:?package=Kanject.Core.CloudFunction.Provider.AwsLambda&version=3.8.0
#tool nuget:?package=Kanject.Core.CloudFunction.Provider.AwsLambda&version=3.8.0
Kanject.Core.CloudFunction.Provider.AwsLambda
The AWS Lambda host for Kanject services. Derive your Lambda class from CloudFunction. Once per execution environment, it builds a Microsoft.Extensions.Hosting container that holds:
- configuration from
appsettings*.jsonand environment variables; - console logging, which Lambda forwards to CloudWatch;
- the services you register in
ConfigureServices.
Your handler methods then resolve services from a ready ServiceProvider. Pair the package with the Kanject.Core.CloudFunction.Aws.Annotations source generator and the host class shrinks to a single ConfigureServices method.
Installation
dotnet add package Kanject.Core.CloudFunction.Provider.AwsLambda
dotnet add package Amazon.Lambda.Serialization.SystemTextJson
Recommended setup, with the source generator:
<ItemGroup>
<PackageReference Include="Kanject.Core.CloudFunction.Provider.AwsLambda" />
<PackageReference Include="Kanject.Core.CloudFunction.Aws.Annotations" PrivateAssets="all" />
<PackageReference Include="Amazon.Lambda.Serialization.SystemTextJson" />
</ItemGroup>
Targets .NET 8, .NET 9 and .NET 10. Native AOT / trimming compatible (see Native AOT). The package brings in Kanject.Core.CloudFunction.Abstractions, Amazon.Lambda.Core and Amazon.Lambda.SNSEvents. It also depends on the generator package. Reference that package yourself, as shown above, so the generator version is explicit.
| You are building | Install |
|---|---|
| A Lambda function with a generated host (recommended) | this package, Kanject.Core.CloudFunction.Aws.Annotations (with PrivateAssets="all"), Amazon.Lambda.Serialization.SystemTextJson |
| A Lambda function with a hand-written host | this package, Amazon.Lambda.Serialization.SystemTextJson |
| A library that only needs the contracts, enums or attributes | Kanject.Core.CloudFunction.Abstractions |
Quick start
A Lambda project usually splits the host class into two partial files: one that configures it and one that holds the handlers.
// Functions.Configuration.cs
using Kanject.Core.CloudFunction.Abstractions.Attributes;
using Kanject.Core.CloudFunction.Abstractions.Enums;
using Microsoft.Extensions.DependencyInjection;
namespace Orders.Lambda;
public sealed class AppSettings
{
public string TableName { get; set; } = string.Empty;
}
[CloudFunctionHost(DebugEnvironment = CloudFunctionEnvironment.Development)]
[RequireConfigSection<AppSettings>("AppSettings")]
public partial class Functions
{
public override void ConfigureServices(IServiceCollection services)
{
services.AddSingleton(AppSettings); // generated, bound and validated at cold start
services.AddScoped<OrderService>();
}
}
// Functions.cs
using Amazon.Lambda.Core;
using Microsoft.Extensions.DependencyInjection;
namespace Orders.Lambda;
public partial class Functions
{
public async Task<OrderReceipt> PlaceOrderAsync(PlaceOrderRequest request, ILambdaContext context)
{
using var scope = ServiceScope;
var orders = scope.ServiceProvider.GetRequiredService<OrderService>();
return await orders.PlaceAsync(request);
}
}
OrderService, PlaceOrderRequest and OrderReceipt are your own types. The generator supplies the base class, constructor, OnStartup and [assembly: LambdaSerializer(...)]; the Kanject.Core.CloudFunction.Aws.Annotations package shows the exact output.
Configuration comes from appsettings.json next to the deployed assembly:
{
"AppSettings": { "TableName": "orders" }
}
Make sure the settings files are included in the publish output:
<ItemGroup>
<None Update="appsettings*.json" CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="PreserveNewest" />
</ItemGroup>
Point the Lambda function's handler at the method, using the class-library form Assembly::Namespace.Type::Method, for example Orders.Lambda::Orders.Lambda.Functions::PlaceOrderAsync. To choose appsettings.{Environment}.json, set ASPNETCORE_LAMBDA_ENVIRONMENT (or ASPNETCORE_ENVIRONMENT) on the function.
How the host starts
When Lambda constructs your Functions instance, the base constructor calls Build(). The host lives in a static field and is built once per process under a lock, so later instances and warm invocations reuse the same container. The build runs these steps in order:
- Environment. The environment name comes from
ASPNETCORE_LAMBDA_ENVIRONMENT, thenASPNETCORE_ENVIRONMENT; surrounding quotes are trimmed. If you pass aCloudFunctionEnvironmentto the base constructor, its member name (for exampleStaging) overrides both. - Configuration. The host loads
appsettings.json,appsettings.{Environment}.jsonand environment variables (all optional, read from the current directory), then callsOnStartup(configurationBuilder)so you can add sources. - Logging. It clears the default providers, adds the console provider, then calls
ConfigureLogging(ILoggingBuilder). - Services. It calls
AddOptions(), thenRegisterFrameworkServices(services), then yourConfigureServices(services). In theDevelopmentenvironment, the container validates scopes and registrations as it is built. - Start. The host is started, so every
IHostedServiceandBackgroundServiceyou or a framework service registered runs itsStartAsync— for example thePrintInConsolelogging that[CloudFunctionHost(EnablePrintInConsoleLogging = true)]wires. The constructor waits until they have all started. - Post-build.
Configure(IServiceProvider)runs once per process, after the host has started. Override it for cold-start warm-up; by default it does nothing.
Every instance, including ones constructed after the first, gets the same ServiceProvider and Configuration. Kanject's SQS queue consumers are hosted services too, but they only poll when their queue sets WatchQueue = true, so starting the host in Lambda doesn't make them compete with the event source mapping. Any other hosted service you register does run, for as long as the execution environment is active.
Members available to your class:
| Member | Purpose |
|---|---|
Configuration |
The built IConfiguration, available in ConfigureServices and afterwards. |
ServiceProvider (protected) |
The root service provider. Resolve singletons from it. |
ServiceScope (protected) |
Creates a new IServiceScope on each access; dispose it. Resolve scoped services from it once per invocation. |
CurrentAspNetEnvironment (protected, static) |
The resolved environment name. |
Hand-written host
You don't need the generator. Derive from CloudFunction and implement its two abstract members yourself:
using Amazon.Lambda.Core;
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) { }
public override void ConfigureServices(IServiceCollection services)
{
var settings = Configuration.GetSection("AppSettings").Get<AppSettings>()
?? throw new InvalidOperationException("'AppSettings' is required.");
services.AddSingleton(settings);
services.AddScoped<OrderService>();
}
}
OnStartup and ConfigureServices are abstract. Configure, ConfigureLogging and RegisterFrameworkServices are virtual no-ops that you can override. If the generator package is installed, its KANCF100 suggestion offers to convert a host of this shape to [CloudFunctionHost].
SQS-triggered functions
Kanject.Core.Queue.Provider.AwsSqs doesn't depend on this package. The two connect through IServiceProvider:
- Register your queue consumers in
ConfigureServices, as that package describes. - Dispatch each
SQSEventfrom a handler through the host'sServiceProvider.
using Amazon.Lambda.SQSEvents;
using Kanject.Core.Queue.Provider.AwsSqs.Abstractions.Extensions;
using Kanject.Core.Queue.Provider.AwsSqs.Extensions;
namespace Orders.Lambda;
public partial class Functions
{
// One queue, one consumer.
public Task<SQSBatchResponse> OrderPlacedAsync(SQSEvent sqsEvent)
=> ServiceProvider.ProcessSqsEventWithQueueConsumerAsync<OrderPlacedConsumer>(sqsEvent);
// One queue carrying several message types, fanned out to route consumers.
public Task<SQSBatchResponse> OrderEventsAsync(SQSEvent sqsEvent)
=> ServiceProvider.RouteIncomingSqsQueueEventAsync(sqsEvent, queue: "order-events");
}
OrderPlacedConsumer is a queue consumer declared with Kanject.Core.Queue.Provider.AwsSqs. Both calls return an SQSBatchResponse that lists the failed messages. Enable ReportBatchItemFailures on the event source mapping so that SQS retries only those messages.
Native AOT
The package is annotated for trimming and Native AOT. For an AOT-published function, derive from Kanject.Core.CloudFunction.Provider.AwsLambda.Aot.CloudFunction, or set [CloudFunctionHost(EnableAot = true)] when you use the generator. The AOT variant has the same members and lifecycle (it starts the host and calls Configure once per process), but builds on HostApplicationBuilder and resolves environment names without reflection. Every CloudFunctionEnvironment member maps to its own name.
Your own registrations and your Lambda serializer must also be AOT-safe. SnsTopicHelper.GetEventTopicPayload<TEventArgs> uses reflection-based System.Text.Json and is marked [RequiresUnreferencedCode] / [RequiresDynamicCode].
Health checks
CloudFunction implements ICloudFunctionHealthCheck<CloudFunction>, so you can register checks once and run them from a handler:
namespace Orders.Lambda;
public partial class Functions
{
public override void Configure(IServiceProvider serviceProvider)
{
AddHealthCheckEndpoint("orders-api", "https://orders.example.com/health");
}
public void HealthCheck() => PerformHealthCheck();
}
An endpoint check sends an HTTP GET and logs whether it succeeded. Endpoints that require a token get a bearer header from the delegate you pass, or from AddHealthCheckEndpointAccessTokenFunc; the token is fetched before the request is sent. AddHealthCheckFunction<T> registers a named delegate; the check awaits its task and reports a failure when the delegate throws or its task faults. The checks run concurrently. PerformHealthCheck() returns once all of them have finished, blocking the calling thread; await PerformHealthCheckAsync(cancellationToken) is the non-blocking form. Results go to the console log and are not returned, and a failing check never throws.
Public surface at a glance
| Type / member | Purpose |
|---|---|
CloudFunction |
Host base class: builds configuration, logging and DI once per process. |
Aot.CloudFunction |
The same host built on HostApplicationBuilder, for Native AOT. |
OnStartup, ConfigureServices |
Abstract: add configuration sources; register services. |
Configure, ConfigureLogging, RegisterFrameworkServices |
Virtual hooks: post-build work; extra logging providers; framework registrations. |
AddHealthCheckEndpoint, AddHealthCheckFunction<T>, PerformHealthCheck, PerformHealthCheckAsync |
Health-check registration and execution. |
LambdaContextExtensions.GetFunctionAlias(ILambdaContext) |
Returns the last : segment of InvokedFunctionArn (the alias or version when invoked through a qualified ARN). |
LambdaLoggerExtension.LogError(ILambdaLogger, Exception) / LogError(ILambdaLogger, string, Exception) |
Writes the message, stack trace and inner exception through LogLine. |
SnsTopicHelper.GetTopic(string topicArn) |
Returns the lower-cased topic name from an SNS topic ARN. |
SnsTopicHelper.GetEventTopicPayload<TEventArgs>(SNSEvent.SNSMessage) |
Deserializes an SNS message body to TEventArgs. |
ControllerBaseExtensions.GetClientCountryCode<TControllerBase>() |
For ASP.NET Core controllers: reads the caller's country from X-Country, CloudFront-Viewer-Country or CF-IPCountry. |
Namespaces: Kanject.Core.CloudFunction.Provider.AwsLambda (and .Aot, .Extensions, .Helpers).
Related packages
| Package | Role | Availability |
|---|---|---|
Kanject.Core.CloudFunction.Abstractions |
The contracts, enums and [CloudFunctionHost] / [RequireConfigSection<T>] attributes this host implements |
nuget.org |
Kanject.Core.CloudFunction.Aws.Annotations |
Source generator and analyzers that write the host plumbing for you | nuget.org |
Kanject.Core.Api.Aws.Extensions |
Parameter Store configuration source (AddAwsSystemManagerParameterStore) for OnStartup |
nuget.org |
Kanject.Core.Queue.Provider.AwsSqs |
SQS queue consumers dispatched from 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.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. 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 is compatible. 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 is compatible. 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. |
-
net10.0
- Amazon.Lambda.Core (>= 3.3.0)
- Amazon.Lambda.SNSEvents (>= 3.0.1)
- Kanject.Core.CloudFunction.Abstractions (>= 3.10.0)
- Kanject.Core.CloudFunction.Aws.Annotations (>= 1.7.0)
-
net8.0
- Amazon.Lambda.Core (>= 3.3.0)
- Amazon.Lambda.SNSEvents (>= 3.0.1)
- Kanject.Core.CloudFunction.Abstractions (>= 3.10.0)
- Kanject.Core.CloudFunction.Aws.Annotations (>= 1.7.0)
-
net9.0
- Amazon.Lambda.Core (>= 3.3.0)
- Amazon.Lambda.SNSEvents (>= 3.0.1)
- Kanject.Core.CloudFunction.Abstractions (>= 3.10.0)
- Kanject.Core.CloudFunction.Aws.Annotations (>= 1.7.0)
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 |
|---|---|---|
| 3.9.0 | 4 | 10/5/2026 |
| 3.8.0 | 47 | 10/2/2026 |
| 3.7.1 | 110 | 9/27/2026 |
| 3.7.0 | 83 | 9/27/2026 |
| 3.6.7 | 87 | 9/26/2026 |
| 3.6.6 | 116 | 9/7/2026 |
| 3.6.5 | 100 | 8/27/2026 |
| 3.6.4 | 107 | 8/22/2026 |
| 3.6.3 | 118 | 8/10/2026 |
| 3.6.2 | 109 | 8/9/2026 |
| 3.6.1 | 115 | 8/5/2026 |
| 3.6.0 | 109 | 8/5/2026 |
| 3.5.0 | 121 | 8/3/2026 |
| 3.4.7 | 132 | 7/30/2026 |
| 3.4.6 | 124 | 7/18/2026 |
| 3.4.5 | 139 | 7/13/2026 |
| 3.4.4 | 125 | 7/11/2026 |
| 3.4.3 | 124 | 7/11/2026 |
| 3.4.2 | 124 | 7/9/2026 |
| 3.4.1 | 122 | 7/9/2026 |