You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS Lambda中AddScoped注册服务跨请求复用实例问题

问题根因

出现这个现象的核心原因是.NET依赖注入的Scoped生命周期规则和AWS Lambda的执行模型没有对齐:

  • .NET原生DI框架中,AddScoped注册的服务实例生命周期和独立的IServiceScope作用域绑定。如果直接从根ServiceProvider解析Scoped服务,服务实例会和根容器的生命周期完全绑定,实际表现和Singleton单例完全一致。
  • AWS Lambda的执行逻辑是:冷启动时仅执行一次Function构造函数,只要实例没有被平台回收(热启动阶段),所有后续函数调用都会复用构造函数中初始化的根_serviceProvider实例。你一直直接从根容器解析服务,没有为每次Lambda调用创建独立的请求级作用域,自然Scoped服务不会按调用维度重新生成。
  • 你之前使用AddTransient能正常工作,是因为Transient生命周期的服务每次解析都会生成新实例,不依赖独立作用域的创建逻辑。
修复方案

在每次Lambda函数触发(即FunctionHandler方法执行)时,先基于根容器创建一个独立的DI作用域,本次调用的所有服务都从这个请求级作用域解析,调用结束后自动释放作用域,就能实现「同一次请求内Scoped服务实例相同,不同请求返回独立实例」的预期效果。
修改后的FunctionHandler代码如下:

public string FunctionHandler(object input, ILambdaContext context)
{
    // 为当前Lambda调用创建独立的DI作用域,调用结束后自动释放
    using var scope = _serviceProvider.CreateScope();
    // 所有服务均从当前请求作用域解析,不要直接从根_serviceProvider获取
    var tenantInfo= scope.ServiceProvider.GetRequiredService<ITenantInfo>();
    var service1 = scope.ServiceProvider.GetRequiredService<IService1>();
    var service2 = scope.ServiceProvider.GetRequiredService<IService2>();

    // 原有业务逻辑
    LambdaLogger.Log("Service 1 GUID==>" + service1.GetTenantInfo().GUID); 
    LambdaLogger.Log(Environment.NewLine);

    LambdaLogger.Log("Service 2 GUID==>" + service2.GetTenantInfo().GUID);
    LambdaLogger.Log(Environment.NewLine);

    return "Done";
}
注意事项

不要为了实现效果把BuildServiceProvider逻辑挪到FunctionHandler里、每次调用都重建根容器:这种写法会让所有注册的服务不管声明什么生命周期,都会在每次调用时重新初始化,既浪费Lambda热启动的性能优化优势,也会导致同一次请求内的Scoped服务无法共享实例,不符合DI生命周期设计预期。

内容的提问来源于stack exchange,提问作者John Smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 03:16:06