-
Notifications
You must be signed in to change notification settings - Fork 488
/
Copy pathServiceCollectionExtensions.cs
123 lines (107 loc) · 5.48 KB
/
ServiceCollectionExtensions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
using Amazon.Lambda.AspNetCoreServer.Hosting;
using Amazon.Lambda.AspNetCoreServer.Internal;
using Amazon.Lambda.AspNetCoreServer.Hosting.Internal;
using Amazon.Lambda.Core;
using Amazon.Lambda.Serialization.SystemTextJson;
using Microsoft.Extensions.DependencyInjection.Extensions;
using System.Text.Json.Serialization;
using System.Diagnostics.CodeAnalysis;
namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// Enum for the possible event sources that will send HTTP request into the ASP.NET Core Lambda function.
/// </summary>
public enum LambdaEventSource
{
/// <summary>
/// API Gateway REST API
/// </summary>
RestApi,
/// <summary>
/// API Gateway HTTP API
/// </summary>
HttpApi,
/// <summary>
/// ELB Application Load Balancer
/// </summary>
ApplicationLoadBalancer,
/// <summary>
/// Amazon Bedrock Agent API
/// </summary>
BedrockAgentApi
}
/// <summary>
/// Extension methods to IServiceCollection.
/// </summary>
public static class ServiceCollectionExtensions
{
/// <summary>
/// Add the ability to run the ASP.NET Core Lambda function in AWS Lambda. If the project is not running in Lambda
/// this method will do nothing allowing the normal Kestrel webserver to host the application.
/// </summary>
/// <param name="services"></param>
/// <param name="eventSource"></param>
/// <returns></returns>
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("For Native AOT the overload passing in a SourceGeneratorLambdaJsonSerializer instance must be used to avoid reflection with JSON serialization.")]
public static IServiceCollection AddAWSLambdaHosting(this IServiceCollection services, LambdaEventSource eventSource)
{
// Not running in Lambda so exit and let Kestrel be the web server
return services.AddAWSLambdaHosting(eventSource, (Action<HostingOptions>?)null);
}
/// <summary>
/// Add the ability to run the ASP.NET Core Lambda function in AWS Lambda. If the project is not running in Lambda
/// this method will do nothing allowing the normal Kestrel webserver to host the application.
/// </summary>
/// <param name="services"></param>
/// <param name="eventSource"></param>
/// <param name="configure"></param>
/// <returns></returns>
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("For Native AOT the overload passing in a SourceGeneratorLambdaJsonSerializer instance must be used to avoid reflection with JSON serialization.")]
public static IServiceCollection AddAWSLambdaHosting(this IServiceCollection services, LambdaEventSource eventSource, Action<HostingOptions>? configure = null)
{
if (TryLambdaSetup(services, eventSource, configure, out var hostingOptions))
{
services.TryAddSingleton<ILambdaSerializer>(hostingOptions!.Serializer ?? new DefaultLambdaJsonSerializer());
}
return services;
}
/// <summary>
/// Add the ability to run the ASP.NET Core Lambda function in AWS Lambda. If the project is not running in Lambda
/// this method will do nothing allowing the normal Kestrel webserver to host the application.
/// </summary>
/// <param name="services"></param>
/// <param name="eventSource"></param>
/// <param name="serializer"></param>
/// <param name="configure"></param>
/// <returns></returns>
public static IServiceCollection AddAWSLambdaHosting<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>(this IServiceCollection services, LambdaEventSource eventSource, SourceGeneratorLambdaJsonSerializer<T> serializer, Action<HostingOptions>? configure = null)
where T : JsonSerializerContext
{
if(TryLambdaSetup(services, eventSource, configure, out var hostingOptions))
{
services.TryAddSingleton<ILambdaSerializer>(serializer ?? hostingOptions!.Serializer);
}
return services;
}
private static bool TryLambdaSetup(IServiceCollection services, LambdaEventSource eventSource, Action<HostingOptions>? configure, out HostingOptions? hostingOptions)
{
hostingOptions = null;
// Not running in Lambda so exit and let Kestrel be the web server
if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("AWS_LAMBDA_FUNCTION_NAME")))
return false;
hostingOptions = new HostingOptions();
if (configure != null)
configure.Invoke(hostingOptions);
var serverType = eventSource switch
{
LambdaEventSource.HttpApi => typeof(APIGatewayHttpApiV2LambdaRuntimeSupportServer),
LambdaEventSource.RestApi => typeof(APIGatewayRestApiLambdaRuntimeSupportServer),
LambdaEventSource.ApplicationLoadBalancer => typeof(ApplicationLoadBalancerLambdaRuntimeSupportServer),
LambdaEventSource.BedrockAgentApi => typeof(BedrockAgentApiLambdaRuntimeSupportServer),
_ => throw new ArgumentException($"Event source type {eventSource} unknown")
};
Utilities.EnsureLambdaServerRegistered(services, serverType);
return true;
}
}
}