Skip to content

Commit bd06753

Browse files
Merge branch 'dev'
2 parents 89c567d + 05d63ee commit bd06753

38 files changed

Lines changed: 1104 additions & 44 deletions

File tree

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
## Release 2026-05-18
2+
3+
### Amazon.Lambda.Core (3.1.0)
4+
* [Preview] Add LambdaLogger.ConfigureStructuredLogging to customize the JsonSerializerOptions used for serializing logging parameters.
5+
* Add preview ILambdaSerializer Serializer property to ILambdaContext (default-implemented to null on net8.0+) so user code can access the serializer registered with the runtime. Marked [Experimental("AWSLAMBDA001")]; class-library mode requires an updated managed Lambda runtime to populate this property. The Experimental flag will be removed in a follow-up release once the managed runtime is deployed.
6+
### Amazon.Lambda.RuntimeSupport (2.1.0)
7+
* Add support for handling the structured logging customization from Amazon.Lambda.Core.
8+
* Propagate the registered ILambdaSerializer to the per-invocation ILambdaContext.Serializer. Surfaces the new preview ILambdaContext.Serializer (AWSLAMBDA001); the Experimental flag will be removed in a follow-up release once the managed runtime is deployed.
9+
### Amazon.Lambda.Annotations (2.0.1)
10+
* Fix CS0121 ambiguity error in generated Program.g.cs when a Lambda handler has no input parameters and returns Task. The source generator now uses the unambiguous LambdaBootstrapBuilder.Create(Func<Stream, Task>) overload for this case.
11+
### Amazon.Lambda.TestUtilities (4.1.0)
12+
* Add Serializer setter to TestLambdaContext to mirror the new preview ILambdaContext.Serializer property. Marked [Experimental("AWSLAMBDA001")]; the Experimental flag will be removed in a follow-up release once the managed runtime is deployed.
13+
### Amazon.Lambda.AspNetCoreServer (10.1.1)
14+
* Fix InvokeFeatures.Set<TFeature> to bump the feature collection revision so middleware that wraps the response body (e.g. OutputCache, ResponseCompression) is properly visible to ASP.NET Core's FeatureReferences cache. Resolves https://github.com/aws/aws-lambda-dotnet/issues/1702 where IOutputCache stored empty response bodies.
15+
116
## Release 2026-05-15
217

318
### Amazon.Lambda.AspNetCoreServer (10.1.0)

Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Amazon.Lambda.Annotations.SourceGenerator.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
2222
<IncludeBuildOutput>false</IncludeBuildOutput>
2323

24-
<Version>2.0.0</Version>
24+
<Version>2.0.1</Version>
2525
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
2626
</PropertyGroup>
2727

Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/ExecutableAssembly.cs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,64 @@ public static async Task Main(string[] args)
142142

143143
#line 45 "C:\codebase\V3\HLL\aws-lambda-dotnet\Libraries\src\Amazon.Lambda.Annotations.SourceGenerator\Templates\ExecutableAssembly.tt"
144144

145+
}
146+
else if (!model.GeneratedMethod.Parameters.Any() && model.LambdaMethod.ReturnsVoidTask)
147+
{
148+
149+
150+
#line default
151+
#line hidden
152+
this.Write(" Func<Stream, System.Threading.Tasks.Task> ");
153+
154+
#line default
155+
#line hidden
156+
this.Write(this.ToStringHelper.ToStringWithCulture(model.LambdaMethod.ExecutableAssemblyHandlerName));
157+
158+
#line default
159+
#line hidden
160+
this.Write(" = new ");
161+
162+
#line default
163+
#line hidden
164+
this.Write(this.ToStringHelper.ToStringWithCulture(model.LambdaMethod.ContainingNamespace));
165+
166+
#line default
167+
#line hidden
168+
this.Write(".");
169+
170+
#line default
171+
#line hidden
172+
this.Write(this.ToStringHelper.ToStringWithCulture(model.LambdaMethod.ContainingType.Name));
173+
174+
#line default
175+
#line hidden
176+
this.Write("_");
177+
178+
#line default
179+
#line hidden
180+
this.Write(this.ToStringHelper.ToStringWithCulture(model.LambdaMethod.Name));
181+
182+
#line default
183+
#line hidden
184+
this.Write("_Generated().");
185+
186+
#line default
187+
#line hidden
188+
this.Write(this.ToStringHelper.ToStringWithCulture(model.LambdaMethod.Name));
189+
190+
#line default
191+
#line hidden
192+
this.Write(";\r\n await Amazon.Lambda.RuntimeSupport.LambdaBootstrapBuilder.Crea" +
193+
"te(");
194+
195+
#line default
196+
#line hidden
197+
this.Write(this.ToStringHelper.ToStringWithCulture(model.LambdaMethod.ExecutableAssemblyHandlerName));
198+
199+
#line default
200+
#line hidden
201+
this.Write(").Build().RunAsync();\r\n break;\r\n");
202+
145203
}
146204
else
147205
{

Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/ExecutableAssembly.tt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@ public class GeneratedProgram
4343
await Amazon.Lambda.RuntimeSupport.LambdaBootstrapBuilder.Create(<#= model.LambdaMethod.ExecutableAssemblyHandlerName #>, new <#= this._lambdaFunctions[0].SerializerInfo.SerializerName #>()).Build().RunAsync();
4444
break;
4545
<#
46+
}
47+
else if (!model.GeneratedMethod.Parameters.Any() && model.LambdaMethod.ReturnsVoidTask)
48+
{
49+
// No typed input and Task return: Func<Stream, Task> is ambiguous between
50+
// Create<TInput>(Func<TInput, Task>, ILambdaSerializer) and
51+
// Create<TOutput>(Func<Stream, TOutput>, ILambdaSerializer).
52+
// Use the non-generic, non-serializer overload to resolve CS0121.
53+
#>
54+
Func<Stream, System.Threading.Tasks.Task> <#= model.LambdaMethod.ExecutableAssemblyHandlerName #> = new <#= model.LambdaMethod.ContainingNamespace #>.<#= model.LambdaMethod.ContainingType.Name #>_<#= model.LambdaMethod.Name #>_Generated().<#= model.LambdaMethod.Name #>;
55+
await Amazon.Lambda.RuntimeSupport.LambdaBootstrapBuilder.Create(<#= model.LambdaMethod.ExecutableAssemblyHandlerName #>).Build().RunAsync();
56+
break;
57+
<#
4658
}
4759
else
4860
{

Libraries/src/Amazon.Lambda.Annotations/Amazon.Lambda.Annotations.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<AssemblyOriginatorKeyFile>..\..\..\buildtools\public.snk</AssemblyOriginatorKeyFile>
1818
<SignAssembly>true</SignAssembly>
1919

20-
<Version>2.0.0</Version>
20+
<Version>2.0.1</Version>
2121
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
2222
</PropertyGroup>
2323

Libraries/src/Amazon.Lambda.AspNetCoreServer/Amazon.Lambda.AspNetCoreServer.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<Description>Amazon.Lambda.AspNetCoreServer makes it easy to run ASP.NET Core Web API applications as AWS Lambda functions.</Description>
77
<TargetFrameworks>$(DefaultPackageTargets)</TargetFrameworks>
88
<AssemblyTitle>Amazon.Lambda.AspNetCoreServer</AssemblyTitle>
9-
<Version>10.1.0</Version>
9+
<Version>10.1.1</Version>
1010
<AssemblyName>Amazon.Lambda.AspNetCoreServer</AssemblyName>
1111
<PackageId>Amazon.Lambda.AspNetCoreServer</PackageId>
1212
<PackageTags>AWS;Amazon;Lambda;aspnetcore</PackageTags>

Libraries/src/Amazon.Lambda.AspNetCoreServer/Internal/InvokeFeatures.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,11 @@ public IEnumerator<KeyValuePair<Type, object>> GetEnumerator()
117117

118118
public void Set<TFeature>(TFeature instance)
119119
{
120-
if (instance == null)
121-
return;
122-
123-
_features[typeof(TFeature)] = instance;
120+
// Delegate to the indexer so _containerRevision is bumped, otherwise
121+
// ASP.NET Core's FeatureReferences cache will return stale feature
122+
// references after middleware (e.g. OutputCache, ResponseCompression)
123+
// wraps the response body via HttpContext.Response.Body = wrapper.
124+
this[typeof(TFeature)] = instance;
124125
}
125126

126127
IEnumerator IEnumerable.GetEnumerator()

Libraries/src/Amazon.Lambda.Core/Amazon.Lambda.Core.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<TargetFrameworks>netstandard2.0;$(DefaultPackageTargets)</TargetFrameworks>
77
<Description>Amazon Lambda .NET Core support - Core package.</Description>
88
<AssemblyTitle>Amazon.Lambda.Core</AssemblyTitle>
9-
<Version>3.0.0</Version>
9+
<Version>3.1.0</Version>
1010
<AssemblyName>Amazon.Lambda.Core</AssemblyName>
1111
<PackageId>Amazon.Lambda.Core</PackageId>
1212
<PackageTags>AWS;Amazon;Lambda</PackageTags>

Libraries/src/Amazon.Lambda.Core/ILambdaContext.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
namespace Amazon.Lambda.Core
22
{
33
using System;
4+
using System.Diagnostics.CodeAnalysis;
45

56
/// <summary>
67
/// Object that allows you to access useful information available within
@@ -95,6 +96,25 @@ public interface ILambdaContext
9596
/// The trace id generated by Lambda for distributed tracing across AWS services.
9697
/// </summary>
9798
string TraceId { get { return string.Empty; } }
99+
100+
/// <summary>
101+
/// The <see cref="ILambdaSerializer"/> the Lambda function registered with the
102+
/// runtime — either the instance passed to
103+
/// <c>LambdaBootstrapBuilder.Create(handler, serializer)</c> /
104+
/// <c>HandlerWrapper.GetHandlerWrapper(handler, serializer)</c>, or the type set
105+
/// via <c>[assembly: LambdaSerializer(typeof(...))]</c> in class-library mode.
106+
/// User code can reuse it for ad-hoc (de)serialization without re-instantiating.
107+
/// Can be null when the function did not register a serializer (e.g., raw-stream
108+
/// handlers).
109+
/// </summary>
110+
/// <remarks>
111+
/// <para><b>Preview API.</b> Class-library mode requires an updated managed
112+
/// Lambda runtime to populate this property; until that ships, the value will
113+
/// be null when running in class-library mode. The <see cref="ExperimentalAttribute"/>
114+
/// is applied to surface this caveat at the call site.</para>
115+
/// </remarks>
116+
[Experimental("AWSLAMBDA001")]
117+
ILambdaSerializer Serializer { get { return null; } }
98118
#endif
99119
}
100120
}

Libraries/src/Amazon.Lambda.Core/LambdaLogger.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,33 @@ public static void Log(string level, Exception exception, string message, params
126126
/// <param name="message">Message to log. The message may have format arguments.</param>
127127
/// <param name="args">Arguments to format the message with.</param>
128128
public static void Log(LogLevel level, Exception exception, string message, params object[] args) => Log(level.ToString(), exception, message, args);
129+
130+
// This field must not be readonly because SetConfigureStructuredLoggingAction replaces the value
131+
// when Amazon.Lambda.RuntimeSupport registers its structured logging callback.
132+
private static Action<StructuredLoggingOptions> _configureStructuredLoggingAction = (options) => _placeHolderStructuredLoggingOptions = options;
133+
134+
// Because a user might call ConfigureStructuredLogging before the Lambda runtime has a chance to replace the _configureStructuredLoggingAction with the
135+
// real implementation, we need to hold onto the options they provided until the Lambda runtime can use them to configure structured logging.
136+
private static StructuredLoggingOptions _placeHolderStructuredLoggingOptions;
137+
138+
/// <summary>
139+
/// When structured logging is enabled this method will allow overriding the default configuration the Lambda runtime uses for structured logging.
140+
/// </summary>
141+
/// <param name="options">The options to use for configuring structured logging.</param>
142+
[RequiresPreviewFeatures("This method is in preview until the latest changes of the .NET Lambda runtime client have been deployed to the Lambda managed runtimes")]
143+
public static void ConfigureStructuredLogging(StructuredLoggingOptions options) => _configureStructuredLoggingAction(options);
144+
145+
internal static void SetConfigureStructuredLoggingAction(Action<StructuredLoggingOptions> configureStructuredLoggingAction)
146+
{
147+
_configureStructuredLoggingAction = configureStructuredLoggingAction;
148+
149+
// If a user set the structured logging options before the Lambda runtime set the real _configureStructuredLoggingAction,
150+
// we need to call it now to make sure the user's options are applied.
151+
if (_placeHolderStructuredLoggingOptions != null)
152+
{
153+
_configureStructuredLoggingAction(_placeHolderStructuredLoggingOptions);
154+
}
155+
}
129156
#endif
130157
}
131158
}

0 commit comments

Comments
 (0)