Singleton/Scoped/Transient服务的实例化时机咨询
ASP.NET Core 不同生命周期服务的实例化时机
注册的服务与控制器代码
服务注册代码:
builder.Services.AddSingleton<IService1, Service1>(); builder.Services.AddScoped<IService2, Service2>(); builder.Services.AddTransient<IService3, Service3>();
控制器示例(其余控制器逻辑类似):
[ApiController] [Route("api/controller1")] public class Controller1 : ControllerBase { private readonly IService1 _service1; public Controller1(IService1 service1) { this._service1 = service1; } [HttpPost("request-1")] public IActionResult Request1() { // Do something with service 1 } }
问题
请问每个服务会在何时被实例化?
我的两种理解:
- 无论生命周期如何,所有服务仅在被请求时才实例化。即调用request-1时仅Service1实例化,调用request-2时才会实例化Service2,以此类推。
- Singleton服务在首次HTTP请求时实例化,Scoped服务每次HTTP请求时实例化,Transient服务即便未被使用也会实例化?
实例化时机说明
针对三种生命周期的服务,实例化时机如下:
- Singleton(单例)服务:仅会被实例化一次,触发时机是首次有依赖它的对象需要被创建时。在你的场景中,就是第一次调用
api/controller1/request-1时,Controller1被构造,此时需要注入IService1,Service1才会被实例化。之后所有涉及IService1的请求都会复用这个实例,不会重新创建。 - Scoped(作用域)服务:在每个HTTP请求的作用域内,首次被依赖时实例化,同一个请求内多次用到该服务会复用同一个实例。你的场景里,只有当调用Controller2对应的接口时,该请求作用域内第一次需要IService2的时候,Service2才会被实例化;每个新的HTTP请求如果用到IService2,都会创建一个新的Service2实例。
- Transient(瞬时)服务:每次被依赖时都会创建新实例,但同样是只有当被需要注入时才会实例化。如果没有任何请求或对象需要IService3,它不会被实例化;只要有依赖需要,每次注入都会生成全新的Service3实例。
对两种理解的验证
你的第一种理解更接近正确逻辑——所有服务都是在被依赖(需要注入)的时候才会实例化,而非提前创建。第二种理解存在以下错误:
- Singleton服务不是在首次HTTP请求就实例化,而是首次被依赖的对象构造时才触发实例化;
- Transient服务不会在未被使用时实例化,只有当被需要时才会创建。
内容的提问来源于stack exchange,提问作者ytan11
相关产品推荐
相关产品推荐

