【问题标题】:Dependency Injection in AWS Lambda function using dotnet core 2.1使用 dotnet core 2.1 在 AWS Lambda 函数中进行依赖注入
【发布时间】:2018-10-01 03:12:06
【问题描述】:

我是 Aws Lambda 的新手,并试图弄清楚如何使用 .net core 2.1 在 Aws Lambda 中使用依赖注入。

我正在尝试注入IHttpClientFactory,但我不确定我是否做得正确。

我在 lambda 函数类的构造函数中调用下面的方法:

  private static IServiceProvider ConfigureServices()
    {
        var serviceCollection = new ServiceCollection();
        serviceCollection.AddHttpClient("client", client =>
        {
            client.BaseAddress = new Uri("someurl");
        });

       return serviceCollection.BuildServiceProvider();
    }

这对吗?

另外,在它返回IServiceProvider 之后,我如何在需要调用IHttpClientFactory 的任何类中使用它?

(我浏览过一些相关的文章,但我仍然不清楚在构造函数中调用时使用ConfigureServices()方法的输出?)

谢谢。

DI 的使用示例:

public class Function
{
   private readonly ITestClass _test;
   public Function()
    {
       ConfigureServices();
    }

    public async Task Handler(ILambdaContext context)
    {
       _test.Run(); //Run method from TestClass that implements ITestClass and calls IHttpClientFactory to make call to an API

      //return something
    }

    private static void ConfigureServices()
    {
        var serviceCollection = new ServiceCollection();
        serviceCollection.AddHttpClient("client", client =>
        {
            client.BaseAddress = new Uri("someurl");
        });
       serviceCollection.AddTransient<ITestClass, TestClass>();
       serviceCollection.BuildServiceProvider(); //is it needed??
    }
}

【问题讨论】:

  • 到目前为止你所拥有的都是可用的。至于您的其他问题,您需要显示一些代码来帮助证明您正在尝试这样做。显示带有上面包含的 sn-p 的示例函数。

标签: c# dependency-injection .net-core aws-lambda


【解决方案1】:

将服务提供者指定为 DI 容器并在您的函数中使用它

函数.cs

public class Function {

    public static Func<IServiceProvider> ConfigureServices = () => {
        var serviceCollection = new ServiceCollection();
        serviceCollection.AddHttpClient("client", client =>
        {
            client.BaseAddress = new Uri("someurl");
        });
        serviceCollection.AddTransient<ITestClass, TestClass>();
        return serviceCollection.BuildServiceProvider();
    };

    static IServiceProvider services;
    static Function() {
        services = ConfigureServices();
    }


    public async Task Handler(ILambdaContext context) {
        ITestClass test = services.GetService<ITestClass>();
        await test.RunAsync(); 

        //...
    }
}

使用静态构造函数进行一次性调用来配置您的服务并构建服务容器。

【讨论】:

  • 谢谢。可以通过模拟 ITestClass 对 Handler() 进行单元测试吗?
  • 您需要通过将ConfigureServices 转换为Func&lt;IServiceProvider&gt; 使ConfigureServices 公开且可覆盖,以便在测试时替换它
  • @Nkosi internal 应该没问题。
  • @coolio 你不需要真正测试句柄。只需测试您的 ITestClass 实现,并测试您的服务实现。如果您正在测试句柄,那么您实际上是在测试 AWS 实施。
  • 这是一个不好的例子。如果 ITestClass 具有 IHttpClientFactory 依赖项,那么如果 lambda 会有并发执行,它将有 SocketException,因为 IHttpClientFactory 应该作为 AWS Lambda 执行上下文的单例创建。所以 ITestClass 测试 = services.GetService();为此,应将其放置在 Function() 构造函数中。
猜你喜欢
  • 2019-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-23
  • 2017-07-14
  • 2017-06-09
  • 2020-11-09
  • 2020-11-30
相关资源
最近更新 更多