AWS Lambda 依赖注入:无法动态创建“TestDep.Function”类型的实例。原因:没有定义无参构造函数

问题描述 投票:0回答:2

我正在尝试在我的 C# Dotnet 6 代码中使用依赖注入来部署到 AWS Lambda 函数。

我不断收到此错误:

无法动态创建“TestDep.Function”类型的实例。原因:没有定义无参数构造函数。

我已经安装了相关的NuGet包:

Amazon.Lambda.Annotations;
Microsoft.Extensions.DependencyInjection;

这些是我的文件:

启动.cs

using System;
using Amazon.Lambda.Annotations;
using Microsoft.Extensions.DependencyInjection;

namespace TestDep
{
    [LambdaStartup]
    public class Startup
    {
        public void ConfigureServices(IServiceCollection serviceCollection)
        {
            serviceCollection.AddTransient<IMyDependency, MyDependency>();

        }
    }
}

我的界面:

namespace TestDep
{
    public interface IMyDependency
    {
        string GetValue(string key);
    }
}

我的实现:

using System;
namespace TestDep
{
    public class MyDependency : IMyDependency
    {
        public MyDependency()
        {
            Value = Guid.NewGuid();
        }

        public Guid Value { get; private set; }

        public string GetValue(string key)
        {
            return $"MyDependency {key} {Value}";

        }
    }
}

我的功能:

using Amazon.Lambda.Annotations;
using Amazon.Lambda.Core;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace TestDep;

public class Function
{
    private readonly IMyDependency _myDependencyCtor;
    public Function(IMyDependency myDependency)
    {
        _myDependencyCtor = myDependency;

    }

    /// <summary>
    /// A simple function that takes a string and does a ToUpper
    /// </summary>
    /// <param name="input"></param>
    /// <param name="context"></param>
    /// <returns></returns>
    [LambdaFunction]
    public List<string> FunctionHandler(string a, ILambdaContext context)
    {
        return new List<string>()
        {
            _myDependencyCtor.GetValue("Constructor"),
            a
        };
    }
}

这是我的 aws-lambda-tools-defaults.json

{
  "Information": [
    "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.",
    "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.",
    "dotnet lambda help",
    "All the command line options for the Lambda command can be specified in this file."
  ],
  "profile": "",
  "region": "",
  "configuration": "Release",
  "function-architecture": "x86_64",
  "function-runtime": "dotnet6",
  "function-memory-size": 256,
  "function-timeout": 30,
  "function-handler": "TestDep::TestDep.Function::FunctionHandler"
}

和我的 serverless.template

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Transform": "AWS::Serverless-2016-10-31",
  "Description": "This template is partially managed by Amazon.Lambda.Annotations (v1.0.0.0).",
  "Resources": {
    "TestDepFunctionFunctionHandlerGenerated": {
      "Type": "AWS::Serverless::Function",
      "Metadata": {
        "Tool": "Amazon.Lambda.Annotations"
      },
      "Properties": {
        "Runtime": "dotnet6",
        "CodeUri": ".",
        "MemorySize": 256,
        "Timeout": 30,
        "Policies": [
          "AWSLambdaBasicExecutionRole"
        ],
        "PackageType": "Zip",
        "Handler": "TestDep::TestDep.Function_FunctionHandler_Generated::FunctionHandler"
      }
    }
  }
}

编辑:

我无法完成这项工作,但我找到了一种解决方法,这样我仍然可以注入参数以使单元测试变得容易。

public class Function
{
    private readonly IMyDependency _myDependencyCtor;
    public Function()
    {
        var serviceCollection = new ServiceCollection();
        ConfigureServices(serviceCollection);
        var serviceProvider = serviceCollection.BuildServiceProvider();

        // Get Configuration Service from DI system
        _myDependencyCtor = serviceProvider.GetService<IMyDependency>();

    }
    public Function(IMyDependency myDependency)
    {
        _myDependencyCtor = myDependency;

    }
    private void ConfigureServices(IServiceCollection serviceCollection)
    {
        // Register services with DI system
        serviceCollection.AddTransient<IMyDependency, MyDependency>();
    }

    /// <summary>
    /// A simple function that takes a string and does a ToUpper
    /// </summary>
    /// <param name="input"></param>
    /// <param name="context"></param>
    /// <returns></returns>
    [LambdaFunction]
    public List<string> FunctionHandler(string a, ILambdaContext context)
    {
        return new List<string>()
        {
            _myDependencyCtor.GetValue("Constructor"),
            a
        };
    }
}
c# amazon-web-services aws-lambda dependency-injection
2个回答
1
投票

您似乎在

aws-lambda-tools-defaults.json
文件中缺少模板链接。您应该能够向其添加
"template": "serverless.template"
,使其开始按预期工作。

{
  "Information": [
    "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.",
    "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.",
    "dotnet lambda help",
    "All the command line options for the Lambda command can be specified in this file."
  ],
  "profile": "",
  "region": "",
  "configuration": "Release",
  "template": "serverless.template",
  "function-architecture": "x86_64",
  "function-runtime": "dotnet6",
  "function-memory-size": 256,
  "function-timeout": 30,
  "function-handler": "TestDep::TestDep.Function::FunctionHandler"
}

另请记下

[LambdaFunction]
函数上的
FunctionHandler(string a, ILambdaContext context)
注释。您可以向其传递参数,这将帮助您像自动生成代码一样编写 serverless.template。

"Description": "An AWS Serverless Application. This template is partially managed by Amazon.Lambda.Annotations (v1.0.0.0)."

例如,如果您创建 API 与 SQS 轮询循环,您的 serverless.template 看起来会有所不同。

[LambdaFunction(Policies = "AWSLambdaSQSQueueExecutionRole", MemorySize = 256, Timeout = 30)]
public async Task FunctionHandler(SQSEvent evnt, ILambdaContext context) 
{ 
    foreach(var message in evnt.Records) 
    { 
      await ProcessMessageAsync(message, context);
    }
}

查看此处了解更多信息:https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.Annotations/README.md


0
投票

我在服务器上遇到了这个问题,而本地一切正常。

我通过将 Handler 的值从 serverless.template 文件复制到 aws-lambda-tools-default.json 文件的函数处理程序中来修复它。

函数处理程序初始值 “MyLambdaApp::MyLambdaApp.Function::MyAppWithS3”

从 serverless.template Handler 复制后的函数处理程序 “MyLambdaApp::MyLambdaApp.Function_MyAppWithS3_Generate::MyAppWithS3”

© www.soinside.com 2019 - 2024. All rights reserved.