.NET Core API中Scoped与Transient服务生命周期的疑问
关于.NET Core API中Scoped服务作用域的疑问与验证
我正在使用.NET Core API,现有代码会在响应中返回GUID。通过Postman调用https://localhost:44362/weatherforecast接口,多次点击SEND测试Scoped和Transient服务:我原本认为Scoped服务应在关闭浏览器前每次请求返回相同唯一ID,而Transient服务每次请求返回不同GUID,但不确定.NET Core API中Scoped服务的请求作用域具体是如何处理的。
相关代码如下:
// 构造函数注入 public WeatherForecastController( ILogger<WeatherForecastController> logger, IOperationTransient transientOperation, IOperationScoped scopedOperation, IOperationSingleton singletonOperation, IOperationSingletonInstance singletonInstanceOperation) { _logger = logger; _transientOperation = transientOperation; _scopedOperation = scopedOperation; _singletonOperation = singletonOperation; _singletonInstanceOperation = singletonInstanceOperation; } [HttpGet] public IEnumerable<WeatherForecast> Get() { var rng = new Random(); return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index), TemperatureC = rng.Next(-20, 55), Summary = _scopedOperation.OperationId.ToString()// Summaries[rng.Next(Summaries.Length)] }).ToArray(); } public interface IOperation { Guid OperationId { get; } }
核心规则与验证说明
- Transient服务:每次请求实例时都会创建新对象,所以每次接口请求获取的Transient实例GUID必然不同,符合预期。
- Scoped服务:作用域是单个HTTP请求的全生命周期——同一次请求内,不管多少次获取该服务实例,GUID都相同;但每次新的HTTP请求都会生成新的Scoped实例。你之前的误解在于混淆了浏览器会话和HTTP请求作用域,Scoped和浏览器会话无关,只绑定单次请求。所以多次点击Postman的SEND(每次都是独立请求),返回的Scoped GUID会不一样,这是正常行为。
- Singleton服务:整个应用运行期间只有一个实例,所有请求获取的GUID都相同。
如果要验证Scoped在同一次请求内的一致性,可以在Get方法中多次解析IOperationScoped,比如:
[HttpGet] public IEnumerable<WeatherForecast> Get([FromServices] IOperationScoped anotherScopedOperation) { // 这里_scopedOperation.OperationId和anotherScopedOperation.OperationId会完全相同 var rng = new Random(); return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index), TemperatureC = rng.Next(-20, 55), Summary = $"Scoped ID: {_scopedOperation.OperationId}, Another Scoped ID: {anotherScopedOperation.OperationId}" }).ToArray(); }
内容的提问来源于stack exchange,提问作者John Smit
相关产品推荐
相关产品推荐

