diff --git a/.csharpierignore b/.csharpierignore
new file mode 100644
index 00000000..37415740
--- /dev/null
+++ b/.csharpierignore
@@ -0,0 +1 @@
+src/AwsLambda.Host.Testing/HostFactoryResolver.cs
\ No newline at end of file
diff --git a/.editorconfig b/.editorconfig
index b3a8c7ed..1693a54e 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -13,4 +13,8 @@ insert_final_newline = true
trim_trailing_whitespace = true
[*.xml]
-indent_size = 4
\ No newline at end of file
+indent_size = 4
+
+[src/AwsLambda.Host.Testing/HostFactoryResolver.cs]
+ij_formatter_enabled = false
+resharper_disable_formatter = true
\ No newline at end of file
diff --git a/.github/workflows/main-build.yaml b/.github/workflows/main-build.yaml
index d3b1fe17..2e35c609 100644
--- a/.github/workflows/main-build.yaml
+++ b/.github/workflows/main-build.yaml
@@ -75,7 +75,7 @@ jobs:
~/.sonar/scanner/dotnet-sonarscanner begin \
/k:"j-d-ha_minimal-lambda" \
/o:"j-d-ha" \
- /d:sonar.exclusions="**/bin/**,**/obj/**,tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/**,**/coverage/**,**/.nuget/**,**/packages/**" \
+ /d:sonar.exclusions="**/bin/**,**/obj/**,tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/**,**/coverage/**,**/.nuget/**,**/packages/**,src/MinimalLambda.Testing/HostFactoryResolver.cs" \
/d:sonar.coverage.exclusions="**/*" \
/d:sonar.token="$SONAR_TOKEN"
dotnet build --no-restore --configuration Release /p:TreatWarningsAsErrors=true
diff --git a/.github/workflows/pr-build.yaml b/.github/workflows/pr-build.yaml
index 7188ff70..5e3c503f 100644
--- a/.github/workflows/pr-build.yaml
+++ b/.github/workflows/pr-build.yaml
@@ -99,7 +99,7 @@ jobs:
~/.sonar/scanner/dotnet-sonarscanner begin \
/k:"j-d-ha_minimal-lambda" \
/o:"j-d-ha" \
- /d:sonar.exclusions="**/bin/**,**/obj/**,tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/**,**/coverage/**,**/.nuget/**,**/packages/**" \
+ /d:sonar.exclusions="**/bin/**,**/obj/**,tests/MinimalLambda.SourceGenerators.UnitTests/Snapshots/**,**/coverage/**,**/.nuget/**,**/packages/**,src/MinimalLambda.Testing/HostFactoryResolver.cs" \
/d:sonar.coverage.exclusions="**/*" \
/d:sonar.token="$SONAR_TOKEN"
diff --git a/.github/workflows/validate-pr-title.yaml b/.github/workflows/validate-pr-title.yaml
index 38fae0aa..ff364d96 100644
--- a/.github/workflows/validate-pr-title.yaml
+++ b/.github/workflows/validate-pr-title.yaml
@@ -45,6 +45,7 @@ jobs:
github
core
docs
+ testing
requireScope: false
subjectPattern: ^[a-z].*
subjectPatternError: Subject must start with lowercase letter
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 65004283..67464db4 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -12,9 +12,13 @@
+
+
+
+
diff --git a/MinimalLambda.sln b/MinimalLambda.sln
index cd134e3f..8413ae0f 100644
--- a/MinimalLambda.sln
+++ b/MinimalLambda.sln
@@ -20,6 +20,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
Directory.Packages.props = Directory.Packages.props
THIRD-PARTY-LICENSES.txt = THIRD-PARTY-LICENSES.txt
mkdocs.yml = mkdocs.yml
+ .editorconfig = .editorconfig
+ .csharpierignore = .csharpierignore
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{827E0CD3-B72D-47B6-A68D-7590B98EB39B}"
@@ -71,6 +73,22 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MinimalLambda.Envelopes.Kaf
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MinimalLambda.Envelopes.CloudWatchLogs", "src\Envelopes\MinimalLambda.Envelopes.CloudWatchLogs\MinimalLambda.Envelopes.CloudWatchLogs.csproj", "{6D40345B-6CCF-4A6C-8FA2-5BE6C693E3F7}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MinimalLambda.Testing", "src\MinimalLambda.Testing\MinimalLambda.Testing.csproj", "{9FA188D7-CF5F-4F87-B292-2AF69994FF12}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MinimalLambda.Testing.UnitTests", "tests\MinimalLambda.Testing.UnitTests\Tests\MinimalLambda.Testing.UnitTests\MinimalLambda.Testing.UnitTests.csproj", "{A8B1FC36-7518-4D9B-9CA1-BF7634229AFF}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MinimalLambda.Testing.UnitTests", "MinimalLambda.Testing.UnitTests", "{47DD369E-341A-4E8F-A227-B1B1E04CB9D6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MinimalLambda.Testing.UnitTests.SimpleLambda", "tests\MinimalLambda.Testing.UnitTests\Lambdas\MinimalLambda.Testing.UnitTests.SimpleLambda\MinimalLambda.Testing.UnitTests.SimpleLambda.csproj", "{7E7B3004-C6C4-4A8C-8610-2A1CB61F834A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MinimalLambda.Testing.UnitTests.DiLambda", "tests\MinimalLambda.Testing.UnitTests\Lambdas\MinimalLambda.Testing.UnitTests.DiLambda\MinimalLambda.Testing.UnitTests.DiLambda.csproj", "{DA971B0E-E028-43E9-9FCE-6ADCD2535AC7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MinimalLambda.Testing.UnitTests.NoEventLambda", "tests\MinimalLambda.Testing.UnitTests\Lambdas\MinimalLambda.Testing.UnitTests.NoEventLambda\MinimalLambda.Testing.UnitTests.NoEventLambda.csproj", "{7350482B-DFDE-4DCD-A0C5-899D5EA00F74}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MinimalLambda.Testing.UnitTests.NoResponseLambda", "tests\MinimalLambda.Testing.UnitTests\Lambdas\MinimalLambda.Testing.UnitTests.NoResponseLambda\MinimalLambda.Testing.UnitTests.NoResponseLambda.csproj", "{381F49C0-297F-4B61-8A82-E9E502E523AD}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Lambdas", "Lambdas", "{D9109C8A-AFA8-49C8-A19C-381500902B4D}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -345,6 +363,78 @@ Global
{6D40345B-6CCF-4A6C-8FA2-5BE6C693E3F7}.Release|x64.Build.0 = Release|Any CPU
{6D40345B-6CCF-4A6C-8FA2-5BE6C693E3F7}.Release|x86.ActiveCfg = Release|Any CPU
{6D40345B-6CCF-4A6C-8FA2-5BE6C693E3F7}.Release|x86.Build.0 = Release|Any CPU
+ {9FA188D7-CF5F-4F87-B292-2AF69994FF12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9FA188D7-CF5F-4F87-B292-2AF69994FF12}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9FA188D7-CF5F-4F87-B292-2AF69994FF12}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {9FA188D7-CF5F-4F87-B292-2AF69994FF12}.Debug|x64.Build.0 = Debug|Any CPU
+ {9FA188D7-CF5F-4F87-B292-2AF69994FF12}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {9FA188D7-CF5F-4F87-B292-2AF69994FF12}.Debug|x86.Build.0 = Debug|Any CPU
+ {9FA188D7-CF5F-4F87-B292-2AF69994FF12}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9FA188D7-CF5F-4F87-B292-2AF69994FF12}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9FA188D7-CF5F-4F87-B292-2AF69994FF12}.Release|x64.ActiveCfg = Release|Any CPU
+ {9FA188D7-CF5F-4F87-B292-2AF69994FF12}.Release|x64.Build.0 = Release|Any CPU
+ {9FA188D7-CF5F-4F87-B292-2AF69994FF12}.Release|x86.ActiveCfg = Release|Any CPU
+ {9FA188D7-CF5F-4F87-B292-2AF69994FF12}.Release|x86.Build.0 = Release|Any CPU
+ {A8B1FC36-7518-4D9B-9CA1-BF7634229AFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A8B1FC36-7518-4D9B-9CA1-BF7634229AFF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A8B1FC36-7518-4D9B-9CA1-BF7634229AFF}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {A8B1FC36-7518-4D9B-9CA1-BF7634229AFF}.Debug|x64.Build.0 = Debug|Any CPU
+ {A8B1FC36-7518-4D9B-9CA1-BF7634229AFF}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A8B1FC36-7518-4D9B-9CA1-BF7634229AFF}.Debug|x86.Build.0 = Debug|Any CPU
+ {A8B1FC36-7518-4D9B-9CA1-BF7634229AFF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A8B1FC36-7518-4D9B-9CA1-BF7634229AFF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A8B1FC36-7518-4D9B-9CA1-BF7634229AFF}.Release|x64.ActiveCfg = Release|Any CPU
+ {A8B1FC36-7518-4D9B-9CA1-BF7634229AFF}.Release|x64.Build.0 = Release|Any CPU
+ {A8B1FC36-7518-4D9B-9CA1-BF7634229AFF}.Release|x86.ActiveCfg = Release|Any CPU
+ {A8B1FC36-7518-4D9B-9CA1-BF7634229AFF}.Release|x86.Build.0 = Release|Any CPU
+ {7E7B3004-C6C4-4A8C-8610-2A1CB61F834A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7E7B3004-C6C4-4A8C-8610-2A1CB61F834A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7E7B3004-C6C4-4A8C-8610-2A1CB61F834A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {7E7B3004-C6C4-4A8C-8610-2A1CB61F834A}.Debug|x64.Build.0 = Debug|Any CPU
+ {7E7B3004-C6C4-4A8C-8610-2A1CB61F834A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7E7B3004-C6C4-4A8C-8610-2A1CB61F834A}.Debug|x86.Build.0 = Debug|Any CPU
+ {7E7B3004-C6C4-4A8C-8610-2A1CB61F834A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7E7B3004-C6C4-4A8C-8610-2A1CB61F834A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7E7B3004-C6C4-4A8C-8610-2A1CB61F834A}.Release|x64.ActiveCfg = Release|Any CPU
+ {7E7B3004-C6C4-4A8C-8610-2A1CB61F834A}.Release|x64.Build.0 = Release|Any CPU
+ {7E7B3004-C6C4-4A8C-8610-2A1CB61F834A}.Release|x86.ActiveCfg = Release|Any CPU
+ {7E7B3004-C6C4-4A8C-8610-2A1CB61F834A}.Release|x86.Build.0 = Release|Any CPU
+ {DA971B0E-E028-43E9-9FCE-6ADCD2535AC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DA971B0E-E028-43E9-9FCE-6ADCD2535AC7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DA971B0E-E028-43E9-9FCE-6ADCD2535AC7}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {DA971B0E-E028-43E9-9FCE-6ADCD2535AC7}.Debug|x64.Build.0 = Debug|Any CPU
+ {DA971B0E-E028-43E9-9FCE-6ADCD2535AC7}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {DA971B0E-E028-43E9-9FCE-6ADCD2535AC7}.Debug|x86.Build.0 = Debug|Any CPU
+ {DA971B0E-E028-43E9-9FCE-6ADCD2535AC7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DA971B0E-E028-43E9-9FCE-6ADCD2535AC7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DA971B0E-E028-43E9-9FCE-6ADCD2535AC7}.Release|x64.ActiveCfg = Release|Any CPU
+ {DA971B0E-E028-43E9-9FCE-6ADCD2535AC7}.Release|x64.Build.0 = Release|Any CPU
+ {DA971B0E-E028-43E9-9FCE-6ADCD2535AC7}.Release|x86.ActiveCfg = Release|Any CPU
+ {DA971B0E-E028-43E9-9FCE-6ADCD2535AC7}.Release|x86.Build.0 = Release|Any CPU
+ {7350482B-DFDE-4DCD-A0C5-899D5EA00F74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7350482B-DFDE-4DCD-A0C5-899D5EA00F74}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7350482B-DFDE-4DCD-A0C5-899D5EA00F74}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {7350482B-DFDE-4DCD-A0C5-899D5EA00F74}.Debug|x64.Build.0 = Debug|Any CPU
+ {7350482B-DFDE-4DCD-A0C5-899D5EA00F74}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7350482B-DFDE-4DCD-A0C5-899D5EA00F74}.Debug|x86.Build.0 = Debug|Any CPU
+ {7350482B-DFDE-4DCD-A0C5-899D5EA00F74}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7350482B-DFDE-4DCD-A0C5-899D5EA00F74}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7350482B-DFDE-4DCD-A0C5-899D5EA00F74}.Release|x64.ActiveCfg = Release|Any CPU
+ {7350482B-DFDE-4DCD-A0C5-899D5EA00F74}.Release|x64.Build.0 = Release|Any CPU
+ {7350482B-DFDE-4DCD-A0C5-899D5EA00F74}.Release|x86.ActiveCfg = Release|Any CPU
+ {7350482B-DFDE-4DCD-A0C5-899D5EA00F74}.Release|x86.Build.0 = Release|Any CPU
+ {381F49C0-297F-4B61-8A82-E9E502E523AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {381F49C0-297F-4B61-8A82-E9E502E523AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {381F49C0-297F-4B61-8A82-E9E502E523AD}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {381F49C0-297F-4B61-8A82-E9E502E523AD}.Debug|x64.Build.0 = Debug|Any CPU
+ {381F49C0-297F-4B61-8A82-E9E502E523AD}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {381F49C0-297F-4B61-8A82-E9E502E523AD}.Debug|x86.Build.0 = Debug|Any CPU
+ {381F49C0-297F-4B61-8A82-E9E502E523AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {381F49C0-297F-4B61-8A82-E9E502E523AD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {381F49C0-297F-4B61-8A82-E9E502E523AD}.Release|x64.ActiveCfg = Release|Any CPU
+ {381F49C0-297F-4B61-8A82-E9E502E523AD}.Release|x64.Build.0 = Release|Any CPU
+ {381F49C0-297F-4B61-8A82-E9E502E523AD}.Release|x86.ActiveCfg = Release|Any CPU
+ {381F49C0-297F-4B61-8A82-E9E502E523AD}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -373,5 +463,13 @@ Global
{71EB7C3D-6EFE-4189-BE50-DC7C83D666F5} = {1C3C52D9-2936-4A0C-A9C8-F330F22B8359}
{DA647025-1B7B-425A-9405-8E015F6DA723} = {1C3C52D9-2936-4A0C-A9C8-F330F22B8359}
{6D40345B-6CCF-4A6C-8FA2-5BE6C693E3F7} = {1C3C52D9-2936-4A0C-A9C8-F330F22B8359}
+ {9FA188D7-CF5F-4F87-B292-2AF69994FF12} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
+ {47DD369E-341A-4E8F-A227-B1B1E04CB9D6} = {0AB3BF05-4346-4AA6-1389-037BE0695223}
+ {A8B1FC36-7518-4D9B-9CA1-BF7634229AFF} = {47DD369E-341A-4E8F-A227-B1B1E04CB9D6}
+ {D9109C8A-AFA8-49C8-A19C-381500902B4D} = {47DD369E-341A-4E8F-A227-B1B1E04CB9D6}
+ {DA971B0E-E028-43E9-9FCE-6ADCD2535AC7} = {D9109C8A-AFA8-49C8-A19C-381500902B4D}
+ {7350482B-DFDE-4DCD-A0C5-899D5EA00F74} = {D9109C8A-AFA8-49C8-A19C-381500902B4D}
+ {381F49C0-297F-4B61-8A82-E9E502E523AD} = {D9109C8A-AFA8-49C8-A19C-381500902B4D}
+ {7E7B3004-C6C4-4A8C-8610-2A1CB61F834A} = {D9109C8A-AFA8-49C8-A19C-381500902B4D}
EndGlobalSection
EndGlobal
diff --git a/THIRD-PARTY-LICENSES.txt b/THIRD-PARTY-LICENSES.txt
index 8373afe4..34bca1ed 100644
--- a/THIRD-PARTY-LICENSES.txt
+++ b/THIRD-PARTY-LICENSES.txt
@@ -306,4 +306,36 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+================================================================================
+
+5. runtime
+--------------------------------------------------------------------------------
+Source: https://github.com/dotnet/runtime
+Version: v10.0.0
+License: MIT License
+
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
================================================================================
\ No newline at end of file
diff --git a/codecov.yml b/codecov.yml
index 853b288d..c8d7fbc2 100644
--- a/codecov.yml
+++ b/codecov.yml
@@ -17,4 +17,6 @@ ignore:
- "tests/**"
- "examples/**"
- "benchmarks/**"
- - "**/Program.cs"
\ No newline at end of file
+ - "**/Program.cs"
+ - "**/Program.cs"
+ - "src/MinimalLambda.Testing/HostFactoryResolver.cs"
diff --git a/scripts/validate-version.sh b/scripts/validate-version.sh
index 33cf0463..4147cfe8 100644
--- a/scripts/validate-version.sh
+++ b/scripts/validate-version.sh
@@ -12,10 +12,10 @@ cd "$DIR" || exit 1
PACKAGE_ID=$(grep -o '[^<]*' *.csproj | head -1 | sed 's/\(.*\)<\/PackageId>/\1/')
# Extract version from Directory.Build.props (BSD grep compatible)
-VERSION=$(grep -o '[^<]*' ../../Directory.Build.props | head -1 | sed 's/\(.*\)<\/VersionPrefix>/\1/')
+VERSION=$(grep -o '[^<]*' ../../Directory.Build.props | head -1 | sed 's/\(.*\)<\/Version>/\1/')
if [[ -z "$PACKAGE_ID" ]] || [[ -z "$VERSION" ]]; then
- echo "Error: Could not extract PackageId or VersionPrefix" >&2
+ echo "Error: Could not extract PackageId or Version" >&2
exit 1
fi
diff --git a/src/MinimalLambda.Abstractions/Options/DefaultLambdaJsonSerializerOptions.cs b/src/MinimalLambda.Abstractions/Options/DefaultLambdaJsonSerializerOptions.cs
new file mode 100644
index 00000000..b30c5b8f
--- /dev/null
+++ b/src/MinimalLambda.Abstractions/Options/DefaultLambdaJsonSerializerOptions.cs
@@ -0,0 +1,35 @@
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Amazon.Lambda.Serialization.SystemTextJson;
+using Amazon.Lambda.Serialization.SystemTextJson.Converters;
+
+namespace MinimalLambda.Options;
+
+/// Provides the default JSON serializer options used by AWS Lambda.
+public static class DefaultLambdaJsonSerializerOptions
+{
+ ///
+ /// Creates a instance that matches the defaults used by
+ /// .
+ ///
+ ///
+ /// Configures null-value ignoring, case-insensitive property names, and the AWS naming policy.
+ /// Adds the AWS-provided converters for dates, memory streams, constant classes, and byte arrays.
+ ///
+ /// Configured JSON serializer options suitable for AWS Lambda payloads.
+ public static JsonSerializerOptions Create()
+ {
+ var options = new JsonSerializerOptions
+ {
+ DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
+ PropertyNameCaseInsensitive = true,
+ PropertyNamingPolicy = new AwsNamingPolicy(),
+ };
+ options.Converters.Add(new DateTimeConverter());
+ options.Converters.Add(new MemoryStreamConverter());
+ options.Converters.Add(new ConstantClassConverter());
+ options.Converters.Add(new ByteArrayConverter());
+
+ return options;
+ }
+}
diff --git a/src/MinimalLambda.Abstractions/Options/EnvelopeOptions.cs b/src/MinimalLambda.Abstractions/Options/EnvelopeOptions.cs
index c25fba1a..6d2645d1 100644
--- a/src/MinimalLambda.Abstractions/Options/EnvelopeOptions.cs
+++ b/src/MinimalLambda.Abstractions/Options/EnvelopeOptions.cs
@@ -1,8 +1,6 @@
using System.Text.Json;
-using System.Text.Json.Serialization;
using System.Xml;
using Amazon.Lambda.Serialization.SystemTextJson;
-using Amazon.Lambda.Serialization.SystemTextJson.Converters;
using MinimalLambda.Envelopes;
namespace MinimalLambda.Options;
@@ -57,28 +55,8 @@ public class EnvelopeOptions
/// not been explicitly configured.
///
///
- public JsonSerializerOptions LambdaDefaultJsonOptions
- {
- get
- {
- if (field is null)
- {
- field = new JsonSerializerOptions
- {
- DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
- PropertyNameCaseInsensitive = true,
- PropertyNamingPolicy = new AwsNamingPolicy(),
- };
- field.Converters.Add(new DateTimeConverter());
- field.Converters.Add(new MemoryStreamConverter());
- field.Converters.Add(new ConstantClassConverter());
- field.Converters.Add(new ByteArrayConverter());
- }
-
- return field;
- }
- set;
- }
+ public JsonSerializerOptions LambdaDefaultJsonOptions { get; set; } =
+ DefaultLambdaJsonSerializerOptions.Create();
/// Gets or sets the XML reader settings used when deserializing Lambda event payloads.
///
diff --git a/src/MinimalLambda.Testing/DeferredHostBuilder.cs b/src/MinimalLambda.Testing/DeferredHostBuilder.cs
new file mode 100644
index 00000000..4b26d5aa
--- /dev/null
+++ b/src/MinimalLambda.Testing/DeferredHostBuilder.cs
@@ -0,0 +1,184 @@
+// Portions of this file are derived from aspnetcore
+// Source:
+// https://github.com/dotnet/aspnetcore/blob/v10.0.0/src/Mvc/Mvc.Testing/src/DeferredHostBuilder.cs
+// Copyright (c) .NET Foundation and Contributors
+// Licensed under the MIT License
+// See THIRD-PARTY-LICENSES.txt file in the project root or visit
+// https://github.com/dotnet/aspnetcore/blob/v10.0.0/LICENSE.txt
+
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+
+namespace MinimalLambda.Testing;
+
+// This host builder captures calls to the IHostBuilder then replays them in the call to
+// ConfigureHostBuilder
+internal sealed class DeferredHostBuilder : IHostBuilder
+{
+ private readonly TaskCompletionSource _entryPointCompletionTcs = new(
+ TaskCreationOptions.RunContinuationsAsynchronously
+ );
+
+ private readonly ConfigurationManager _hostConfiguration = new();
+
+ // This task represents a call to IHost.Start, we create it here preemptively in case the
+ // application
+ // exits due to an exception or because it didn't wait for the shutdown signal
+ private readonly TaskCompletionSource _hostStartTcs = new(
+ TaskCreationOptions.RunContinuationsAsynchronously
+ );
+
+ private Action _configure;
+ private Func? _hostFactory;
+
+ public DeferredHostBuilder() =>
+ _configure = b =>
+ {
+ // Copy the properties from this builder into the builder
+ // that we're going to receive
+ foreach (var pair in Properties)
+ b.Properties[pair.Key] = pair.Value;
+ };
+
+ public Task EntryPointCompletion => _entryPointCompletionTcs.Task;
+
+ public IDictionary