Web开发新手求推荐:可跨请求存储数据计算的依赖注入服务
解决方案:跨请求存储数据并计算平均值的服务选择
嘿,这个问题我刚做Web开发的时候也踩过坑!你已经搞懂了DI的三种生命周期,但确实它们都不能直接满足跨请求存数据的需求——transient每次注入都新建实例,scoped每个请求周期就重置,那该怎么办呢?分两种场景给你说:
场景1:单用户/测试场景(全局共享数据)
如果你的应用只是自己测试用,或者只给单个用户使用,那Singleton生命周期的服务就是最适合的!它的实例在整个应用运行期间只会创建一次,完美跨请求保留数据。
实现步骤:
- 创建计算服务类:
public class AverageCalculatorService { // 私有字段存储累计值和计数,避免外部直接修改 private decimal _totalSum = 0; private int _valueCount = 0; // 添加新数值并返回当前平均值 public decimal AddNewValue(decimal inputValue) { _totalSum += inputValue; _valueCount++; return _totalSum / _valueCount; } // 可选:添加重置方法,方便清空数据 public void ResetCalculation() { _totalSum = 0; _valueCount = 0; } }
- 在Program.cs里注册为Singleton:
builder.Services.AddSingleton<AverageCalculatorService>();
- 控制器里注入并使用:
[ApiController] [Route("api/average")] public class AverageController : ControllerBase { private readonly AverageCalculatorService _calculator; // 通过构造函数注入服务 public AverageController(AverageCalculatorService calculator) { _calculator = calculator; } [HttpGet("add")] public IActionResult AddValue([FromQuery] decimal value) { var currentAverage = _calculator.AddNewValue(value); return Ok(new { CurrentAverage = currentAverage, TotalValues = _calculator._valueCount, TotalSum = _calculator._totalSum }); } }
场景2:多用户场景(用户隔离数据)
如果你的应用要给多个用户用,Singleton就不行了——所有用户会共享同一组sum和count,数据会混乱!这时候推荐用Session会话存储或者分布式缓存,这里给你讲最容易上手的Session方案:
实现步骤:
- 先配置Session(在Program.cs里):
// 添加Session服务 builder.Services.AddSession(options => { options.IdleTimeout = TimeSpan.FromMinutes(30); // 设置会话超时时间 options.Cookie.HttpOnly = true; // 提高安全性 options.Cookie.IsEssential = true; // 标记为必要Cookie,确保能正常使用 }); // 注意:Session中间件要放在MapControllers之前 app.UseSession(); app.MapControllers();
- 给Session扩展支持decimal类型的方法(默认Session只支持基本类型):
public static class SessionExtensions { public static void SetDecimal(this ISession session, string key, decimal value) { // 用不变文化存储,避免解析出错 session.SetString(key, value.ToString(CultureInfo.InvariantCulture)); } public static decimal? GetDecimal(this ISession session, string key) { var valueStr = session.GetString(key); return string.IsNullOrEmpty(valueStr) ? null : decimal.Parse(valueStr, CultureInfo.InvariantCulture); } }
- 控制器里使用Session存储用户专属数据:
[ApiController] [Route("api/average")] public class AverageController : ControllerBase { [HttpGet("add")] public IActionResult AddValue([FromQuery] decimal value) { // 从当前用户的Session读取已有的累计值和计数 var totalSum = HttpContext.Session.GetDecimal("UserSum") ?? 0; var valueCount = HttpContext.Session.GetInt32("UserCount") ?? 0; // 更新计算 totalSum += value; valueCount++; var currentAverage = totalSum / valueCount; // 把更新后的数据存回Session HttpContext.Session.SetDecimal("UserSum", totalSum); HttpContext.Session.SetInt32("UserCount", valueCount); return Ok(new { CurrentAverage = currentAverage, TotalValues = valueCount, TotalSum = totalSum }); } }
进阶方案:持久化存储
如果需要服务器重启后数据不丢失,那就得用数据库了——比如创建一张用户平均值记录表,每次请求时根据用户ID读取数据,更新后再写回数据库。这种方式更可靠,但需要你会操作数据库(比如EF Core)。
总结一下:
- 单用户/测试:用Singleton服务,简单直接
- 多用户:用Session或分布式缓存,保证用户数据隔离
- 需要持久化:用数据库存储
内容的提问来源于stack exchange,提问作者AnetaDev
相关产品推荐
相关产品推荐

