Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .autover/changes/6e13a012-1f93-4e55-90b5-d2dd480d086c.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"Projects": [
{
"Name": "Amazon.Lambda.Core",
"Type": "Minor",
"ChangelogMessages": [
"Add ILambdaSerializer Serializer property to ILambdaContext (default-implemented to null on net8.0+) so user code can access the serializer registered with the runtime"
]
},
{
"Name": "Amazon.Lambda.RuntimeSupport",
"Type": "Minor",
"ChangelogMessages": [
"Expose the registered ILambdaSerializer on HandlerWrapper.Serializer and propagate it to the per-invocation ILambdaContext.Serializer"
]
},
{
"Name": "Amazon.Lambda.TestUtilities",
"Type": "Minor",
"ChangelogMessages": [
"Add Serializer setter to TestLambdaContext to mirror the new ILambdaContext.Serializer property"
]
}
]
}
20 changes: 20 additions & 0 deletions Libraries/src/Amazon.Lambda.Core/ILambdaContext.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace Amazon.Lambda.Core
{
using System;
using System.Diagnostics.CodeAnalysis;

/// <summary>
/// Object that allows you to access useful information available within
Expand Down Expand Up @@ -95,6 +96,25 @@ public interface ILambdaContext
/// The trace id generated by Lambda for distributed tracing across AWS services.
/// </summary>
string TraceId { get { return string.Empty; } }

/// <summary>
/// The <see cref="ILambdaSerializer"/> the Lambda function registered with the
/// runtime — either the instance passed to
/// <c>LambdaBootstrapBuilder.Create(handler, serializer)</c> /
/// <c>HandlerWrapper.GetHandlerWrapper(handler, serializer)</c>, or the type set
/// via <c>[assembly: LambdaSerializer(typeof(...))]</c> in class-library mode.
/// User code can reuse it for ad-hoc (de)serialization without re-instantiating.
/// Can be null when the function did not register a serializer (e.g., raw-stream
/// handlers).
/// </summary>
/// <remarks>
/// <para><b>Preview API.</b> Class-library mode requires an updated managed
/// Lambda runtime to populate this property; until that ships, the value will
/// be null when running in class-library mode. The <see cref="ExperimentalAttribute"/>
/// is applied to surface this caveat at the call site.</para>
/// </remarks>
[Experimental("AWSLAMBDA001")]
ILambdaSerializer Serializer { get { return null; } }
#endif
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ public class HandlerWrapper : IDisposable
/// </summary>
public LambdaBootstrapHandler Handler { get; private set; }

/// <summary>
/// The serializer registered with the wrapper, if any. Surfaced so the
/// runtime bootstrap can attach it to the per-invocation
/// <see cref="ILambdaContext"/>, allowing user code to reuse it.
/// Null for handlers that don't take a typed input/output.
/// </summary>
public ILambdaSerializer Serializer { get; private set; }

private HandlerWrapper(LambdaBootstrapHandler handler)
{
Handler = handler;
Expand Down Expand Up @@ -121,7 +129,7 @@ public static HandlerWrapper GetHandlerWrapper<TInput>(Func<TInput, Task> handle
TInput input = serializer.Deserialize<TInput>(invocation.InputStream);
await handler(input);
return EmptyInvocationResponse;
});
}) { Serializer = serializer };
}

/// <summary>
Expand Down Expand Up @@ -171,7 +179,7 @@ public static HandlerWrapper GetHandlerWrapper<TInput>(Func<TInput, ILambdaConte
TInput input = serializer.Deserialize<TInput>(invocation.InputStream);
await handler(input, invocation.LambdaContext);
return EmptyInvocationResponse;
});
}) { Serializer = serializer };
}

/// <summary>
Expand Down Expand Up @@ -218,7 +226,7 @@ public static HandlerWrapper GetHandlerWrapper<TInput>(Func<TInput, Task<Stream>
{
TInput input = serializer.Deserialize<TInput>(invocation.InputStream);
return new InvocationResponse(await handler(input));
});
}) { Serializer = serializer };
}

/// <summary>
Expand Down Expand Up @@ -265,7 +273,7 @@ public static HandlerWrapper GetHandlerWrapper<TInput>(Func<TInput, ILambdaConte
{
TInput input = serializer.Deserialize<TInput>(invocation.InputStream);
return new InvocationResponse(await handler(input, invocation.LambdaContext));
});
}) { Serializer = serializer };
}

/// <summary>
Expand All @@ -278,7 +286,7 @@ public static HandlerWrapper GetHandlerWrapper<TInput>(Func<TInput, ILambdaConte
/// <returns>A HandlerWrapper</returns>
public static HandlerWrapper GetHandlerWrapper<TOutput>(Func<Task<TOutput>> handler, ILambdaSerializer serializer)
{
var handlerWrapper = new HandlerWrapper();
var handlerWrapper = new HandlerWrapper { Serializer = serializer };
handlerWrapper.Handler = async (invocation) =>
{
TOutput output = await handler();
Expand All @@ -300,7 +308,7 @@ public static HandlerWrapper GetHandlerWrapper<TOutput>(Func<Task<TOutput>> hand
/// <returns>A HandlerWrapper</returns>
public static HandlerWrapper GetHandlerWrapper<TOutput>(Func<Stream, Task<TOutput>> handler, ILambdaSerializer serializer)
{
var handlerWrapper = new HandlerWrapper();
var handlerWrapper = new HandlerWrapper { Serializer = serializer };
handlerWrapper.Handler = async (invocation) =>
{
TOutput output = await handler(invocation.InputStream);
Expand All @@ -322,7 +330,7 @@ public static HandlerWrapper GetHandlerWrapper<TOutput>(Func<Stream, Task<TOutpu
/// <returns>A HandlerWrapper</returns>
public static HandlerWrapper GetHandlerWrapper<TInput, TOutput>(Func<TInput, Task<TOutput>> handler, ILambdaSerializer serializer)
{
var handlerWrapper = new HandlerWrapper();
var handlerWrapper = new HandlerWrapper { Serializer = serializer };
handlerWrapper.Handler = async (invocation) =>
{
TInput input = serializer.Deserialize<TInput>(invocation.InputStream);
Expand All @@ -345,7 +353,7 @@ public static HandlerWrapper GetHandlerWrapper<TInput, TOutput>(Func<TInput, Tas
/// <returns>A HandlerWrapper</returns>
public static HandlerWrapper GetHandlerWrapper<TOutput>(Func<ILambdaContext, Task<TOutput>> handler, ILambdaSerializer serializer)
{
var handlerWrapper = new HandlerWrapper();
var handlerWrapper = new HandlerWrapper { Serializer = serializer };
handlerWrapper.Handler = async (invocation) =>
{
TOutput output = await handler(invocation.LambdaContext);
Expand All @@ -367,7 +375,7 @@ public static HandlerWrapper GetHandlerWrapper<TOutput>(Func<ILambdaContext, Tas
/// <returns>A HandlerWrapper</returns>
public static HandlerWrapper GetHandlerWrapper<TOutput>(Func<Stream, ILambdaContext, Task<TOutput>> handler, ILambdaSerializer serializer)
{
var handlerWrapper = new HandlerWrapper();
var handlerWrapper = new HandlerWrapper { Serializer = serializer };
handlerWrapper.Handler = async (invocation) =>
{
TOutput output = await handler(invocation.InputStream, invocation.LambdaContext);
Expand All @@ -389,7 +397,7 @@ public static HandlerWrapper GetHandlerWrapper<TOutput>(Func<Stream, ILambdaCont
/// <returns>A HandlerWrapper</returns>
public static HandlerWrapper GetHandlerWrapper<TInput, TOutput>(Func<TInput, ILambdaContext, Task<TOutput>> handler, ILambdaSerializer serializer)
{
var handlerWrapper = new HandlerWrapper();
var handlerWrapper = new HandlerWrapper { Serializer = serializer };
handlerWrapper.Handler = async (invocation) =>
{
TInput input = serializer.Deserialize<TInput>(invocation.InputStream);
Expand Down Expand Up @@ -449,7 +457,7 @@ public static HandlerWrapper GetHandlerWrapper<TInput>(Action<TInput> handler, I
TInput input = serializer.Deserialize<TInput>(invocation.InputStream);
handler(input);
return Task.FromResult(EmptyInvocationResponse);
});
}) { Serializer = serializer };
}

/// <summary>
Expand Down Expand Up @@ -499,7 +507,7 @@ public static HandlerWrapper GetHandlerWrapper<TInput>(Action<TInput, ILambdaCon
TInput input = serializer.Deserialize<TInput>(invocation.InputStream);
handler(input, invocation.LambdaContext);
return Task.FromResult(EmptyInvocationResponse);
});
}) { Serializer = serializer };
}

/// <summary>
Expand Down Expand Up @@ -546,7 +554,7 @@ public static HandlerWrapper GetHandlerWrapper<TInput>(Func<TInput, Stream> hand
{
TInput input = serializer.Deserialize<TInput>(invocation.InputStream);
return Task.FromResult(new InvocationResponse(handler(input)));
});
}) { Serializer = serializer };
}

/// <summary>
Expand Down Expand Up @@ -593,7 +601,7 @@ public static HandlerWrapper GetHandlerWrapper<TInput>(Func<TInput, ILambdaConte
{
TInput input = serializer.Deserialize<TInput>(invocation.InputStream);
return Task.FromResult(new InvocationResponse(handler(input, invocation.LambdaContext)));
});
}) { Serializer = serializer };
}

/// <summary>
Expand All @@ -606,7 +614,7 @@ public static HandlerWrapper GetHandlerWrapper<TInput>(Func<TInput, ILambdaConte
/// <returns>A HandlerWrapper</returns>
public static HandlerWrapper GetHandlerWrapper<TOutput>(Func<TOutput> handler, ILambdaSerializer serializer)
{
var handlerWrapper = new HandlerWrapper();
var handlerWrapper = new HandlerWrapper { Serializer = serializer };
handlerWrapper.Handler = (invocation) =>
{
TOutput output = handler();
Expand All @@ -628,7 +636,7 @@ public static HandlerWrapper GetHandlerWrapper<TOutput>(Func<TOutput> handler, I
/// <returns>A HandlerWrapper</returns>
public static HandlerWrapper GetHandlerWrapper<TOutput>(Func<Stream, TOutput> handler, ILambdaSerializer serializer)
{
var handlerWrapper = new HandlerWrapper();
var handlerWrapper = new HandlerWrapper { Serializer = serializer };
handlerWrapper.Handler = (invocation) =>
{
TOutput output = handler(invocation.InputStream);
Expand All @@ -650,7 +658,7 @@ public static HandlerWrapper GetHandlerWrapper<TOutput>(Func<Stream, TOutput> ha
/// <returns>A HandlerWrapper</returns>
public static HandlerWrapper GetHandlerWrapper<TInput, TOutput>(Func<TInput, TOutput> handler, ILambdaSerializer serializer)
{
var handlerWrapper = new HandlerWrapper();
var handlerWrapper = new HandlerWrapper { Serializer = serializer };
handlerWrapper.Handler = (invocation) =>
{
TInput input = serializer.Deserialize<TInput>(invocation.InputStream);
Expand All @@ -673,7 +681,7 @@ public static HandlerWrapper GetHandlerWrapper<TInput, TOutput>(Func<TInput, TOu
/// <returns>A HandlerWrapper</returns>
public static HandlerWrapper GetHandlerWrapper<TOutput>(Func<ILambdaContext, TOutput> handler, ILambdaSerializer serializer)
{
var handlerWrapper = new HandlerWrapper();
var handlerWrapper = new HandlerWrapper { Serializer = serializer };
handlerWrapper.Handler = (invocation) =>
{
TOutput output = handler(invocation.LambdaContext);
Expand All @@ -695,7 +703,7 @@ public static HandlerWrapper GetHandlerWrapper<TOutput>(Func<ILambdaContext, TOu
/// <returns>A HandlerWrapper</returns>
public static HandlerWrapper GetHandlerWrapper<TOutput>(Func<Stream, ILambdaContext, TOutput> handler, ILambdaSerializer serializer)
{
var handlerWrapper = new HandlerWrapper();
var handlerWrapper = new HandlerWrapper { Serializer = serializer };
handlerWrapper.Handler = (invocation) =>
{
TOutput output = handler(invocation.InputStream, invocation.LambdaContext);
Expand All @@ -717,7 +725,7 @@ public static HandlerWrapper GetHandlerWrapper<TOutput>(Func<Stream, ILambdaCont
/// <returns>A HandlerWrapper</returns>
public static HandlerWrapper GetHandlerWrapper<TInput, TOutput>(Func<TInput, ILambdaContext, TOutput> handler, ILambdaSerializer serializer)
{
var handlerWrapper = new HandlerWrapper();
var handlerWrapper = new HandlerWrapper { Serializer = serializer };
handlerWrapper.Handler = (invocation) =>
{
TInput input = serializer.Deserialize<TInput>(invocation.InputStream);
Expand Down
Loading