aws / aws-lambda-dotnet

Libraries, samples and tools to help .NET Core developers develop AWS Lambda functions.
Apache License 2.0
1.57k stars 478 forks source link

Annotations - FunctionHander return type of Task<dynamic> Source Generation fails #1304

Closed Simonl9l closed 1 year ago

Simonl9l commented 2 years ago

Describe the bug

As background we're attempting to wrap this repo in the Annotations Setup that we can leverage the DI code generation to get our C# service implementations into each Cognito trigger implementation.

This single handler uses a Task<dynamic> return type. This results in the following code generation error:

Unable to cast object of type 'Microsoft.CodeAnalysis.CSharp.Symbols.PublicModel.DynamicTypeSymbol' to type 'Microsoft.CodeAnalysis.INamedTypeSymbol'.   at Amazon.Lambda.Annotations.SourceGenerator.Models.TypeModelBuilder.Build(ITypeSymbol symbol, GeneratorExecutionContext context) [<path to csproj>]

The Functions/Handler class then looks like this:

public class Functions
{
    private ILambdaLogger Logger;

    [LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.CamelCaseLambdaJsonSerializer))]

    [LambdaFunction]
     public async Task<dynamic> FunctionHandler(JsonElement cognitoEvent, ILambdaContext context)
     {
         Logger = context.Logger;

         Logger.LogDebug("ENVIRONMENT VARIABLES: " + JsonSerializer.Serialize(System.Environment.GetEnvironmentVariables()));
         Logger.LogDebug("CONTEXT: " + JsonSerializer.Serialize(context));

         Logger.LogDebug("EVENT: " + JsonSerializer.Serialize(cognitoEvent));

         return await new CognitoEventHandlerFactory(Logger).GetHandler(cognitoEvent).HandleTriggerEventAsync();
     }
}

If this is resolvable we can then look to modify the example to pass our DI services though to the Trigger Handles.

Short term the workaround is to have a separate Function Handler with the explicit return types based on the given Trigger Sources combinations, and short circuit the dynamic behavior and deploy multiple Lambdas.

Perhaps in the longer term the Annotation library can use this larger scenario as a use case.

Expected Behavior

Generate a suitable Handler wrapper to support the dynamic return type.

Current Behavior

Unable to cast object of type 'Microsoft.CodeAnalysis.CSharp.Symbols.PublicModel.DynamicTypeSymbol' to type 'Microsoft.CodeAnalysis.INamedTypeSymbol'. at Amazon.Lambda.Annotations.SourceGenerator.Models.TypeModelBuilder.Build(ITypeSymbol symbol, GeneratorExecutionContext context) [<path to csproj>]

Reproduction Steps

clone repo as above and modify the Function handler as above.

Possible Solution

as above

Additional Information/Context

The value proposition is that, from a CDK perspective, we have a single Lambda Handler that services all the triggers so wet don't have to deploy a separate Lambda Function with same code base for each Cognito Trigger for each Handler - for which there can be many.

As such supporting a dynamic return type on a single Function Handler has great value.

AWS .NET SDK and/or Package version used

<PackageReference Include="Amazon.Lambda.Core" Version="2.1.0" />
<PackageReference Include="Amazon.Lambda.APIGatewayEvents" Version="2.4.1" />
<PackageReference Include="Amazon.Lambda.Serialization.SystemTextJson" Version="2.3.0" />
<PackageReference Include="Amazon.Lambda.Annotations" Version="0.7.0-preview" />
<PackageReference Include="AWSSDK.CognitoIdentityProvider" Version="3.7.5.10" />

Targeted .NET Platform

NET 6

Operating System and version

OSX Monterey, Windows 10, Linux

ashishdhingra commented 2 years ago

@Simonl9l I'm unsure if the Annotations Framework supports the dynamic return type. @normj for input.

Simonl9l commented 2 years ago

@ashishdhingra is does not currently support the dynamic type per this issue as raised...build output logging (not included above) indicated to open this issue, so I did.

I seem to have a workaround just now to return a JsonElement, so it's not bothering me; but probably one to support, similar to the Task with no type support that was added in the more recent preview-7 I believe.

More importantly does the Lambda DotNet runtime support such that a dynamic response can actually be passed back to the Lambda runtime.

I'm huge fan of the Annotations Lambda library, and look forward to seeing how it evolves, and is more natively supported by the developer test tools.

ashovlin commented 1 year ago

Improved support for dynamic as either a function return type and/or parameter has been released in Amazon.Lambda.Annotations 0.10.0-preview

github-actions[bot] commented 1 year ago

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.