#if NET6_0_OR_GREATER using System; using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Text.Json; using System.Text.Json.Serialization; using System.Text.Json.Serialization.Metadata; using Amazon.Lambda.Core; using Amazon.Lambda.Serialization.SystemTextJson.Converters; namespace Amazon.Lambda.Serialization.SystemTextJson { /// /// ILambdaSerializer implementation that supports the source generator support of System.Text.Json. To use this serializer define /// a partial JsonSerializerContext class with attributes for the types to be serialized. /// /// [JsonSerializable(typeof(APIGatewayHttpApiV2ProxyRequest))] /// [JsonSerializable(typeof(APIGatewayHttpApiV2ProxyResponse))] /// public partial class APIGatewaySerializerContext : JsonSerializerContext /// { /// } /// /// Register the serializer with the LambdaSerializer attribute specifying the defined JsonSerializerContext /// /// [assembly: LambdaSerializer(typeof(SourceGeneratorLambdaJsonSerializer&ly;APIGatewayExampleImage.MyJsonContext>))] /// /// When the class is compiled it will generate all of the JSON serialization code to convert between JSON and the list types. This /// will avoid any reflection based serialization. /// /// public class SourceGeneratorLambdaJsonSerializer<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TSGContext> : AbstractLambdaJsonSerializer, ILambdaSerializer where TSGContext : JsonSerializerContext { TSGContext _jsonSerializerContext; /// /// The options used to serialize JSON object. /// protected JsonSerializerOptions SerializerOptions { get; } /// /// Constructs instance of serializer. /// public SourceGeneratorLambdaJsonSerializer() : this(null, null) { } /// /// Constructs instance of serializer with the option to customize the JsonSerializerOptions after the /// Amazon.Lambda.Serialization.SystemTextJson's default settings have been applied. /// /// public SourceGeneratorLambdaJsonSerializer(Action customizer) : this(customizer, null) { } /// /// Constructs instance of serializer with the option to customize the JsonWriterOptions after the /// Amazon.Lambda.Serialization.SystemTextJson's default settings have been applied. /// /// public SourceGeneratorLambdaJsonSerializer(Action jsonWriterCustomizer) : this(null, jsonWriterCustomizer) { } /// /// Constructs instance of serializer with the option to customize the JsonWriterOptions after the /// Amazon.Lambda.Serialization.SystemTextJson's default settings have been applied. /// /// /// public SourceGeneratorLambdaJsonSerializer(Action customizer, Action jsonWriterCustomizer) : base(jsonWriterCustomizer) { SerializerOptions = CreateDefaultJsonSerializationOptions(); customizer?.Invoke(this.SerializerOptions); var constructor = typeof(TSGContext).GetConstructor(new Type[] { typeof(JsonSerializerOptions) }); if(constructor == null) { throw new ApplicationException($"The serializer {typeof(TSGContext).FullName} is missing a constructor that takes in JsonSerializerOptions object"); } _jsonSerializerContext = constructor.Invoke(new object[] { this.SerializerOptions }) as TSGContext; } /// protected override void InternalSerialize(Utf8JsonWriter writer, T response) { var jsonTypeInfo = _jsonSerializerContext.GetTypeInfo(typeof(T)) as JsonTypeInfo; if (jsonTypeInfo == null) { throw new JsonSerializerException($"No JsonTypeInfo registered in {_jsonSerializerContext.GetType().FullName} for type {typeof(T).FullName}."); } JsonSerializer.Serialize(writer, response, jsonTypeInfo); } /// protected override T InternalDeserialize(byte[] utf8Json) { var jsonTypeInfo = _jsonSerializerContext.GetTypeInfo(typeof(T)) as JsonTypeInfo; if (jsonTypeInfo == null) { throw new JsonSerializerException($"No JsonTypeInfo registered in {_jsonSerializerContext.GetType().FullName} for type {typeof(T).FullName}."); } return JsonSerializer.Deserialize(utf8Json, jsonTypeInfo); } } } #endif