ASP.NET Core 2应用状态数据无法在请求间存储的问题
我懂你现在的困扰——明明照着MSDN的例子把MyShardData(应该是笔误写成Shard了?正确应该是Shared吧😉)注册成了Singleton单例服务,但两次请求之间数据就是没法保留下来。咱们一步步排查,找出问题所在:
先检查注入方式是否正确
这是最常见的坑:一定要通过构造函数注入获取单例实例,绝对不能在方法里手动new对象。比如控制器里要这么写:public class HomeController : Controller { private readonly MyShardData _sharedData; // 正确姿势:构造函数注入Singleton实例 public HomeController(MyShardData sharedData) { _sharedData = sharedData; } public IActionResult SetMessage() { _sharedData.Message = "这是要共享的消息"; return Ok(); } public IActionResult GetMessage() { return Ok(_sharedData.Message); } }要是你在方法里写
var data = new MyShardData();,那每次请求都会生成新对象,数据肯定没法共享。确认应用有没有意外重启
Singleton的生命周期和应用程序是绑定的,如果应用因为代码变更(比如开发环境的热重载)、资源不足或者配置问题重启了,单例里的数据就会被清空。
你可以在MyShardData的构造函数里加个日志输出,看看是不是每次请求都触发了构造:public class MyShardData { public string Message { get; set; } public MyShardData() { Console.WriteLine("MyShardData 实例被创建了!"); } }如果每次请求都打印这句话,要么是服务没注册成Singleton,要么就是应用在频繁重启。
检查服务注册的配置有没有错
确保在Startup.cs的ConfigureServices里只调用了一次services.AddSingleton<MyShardData>();,别不小心写成AddScoped或者AddTransient了——这俩都是每次请求(或每次获取)生成新实例,根本没法共享数据。
你可以在注册完服务后加个日志确认:services.AddSingleton<MyShardData>(); Console.WriteLine("MyShardData 已注册为Singleton单例服务");留意开发环境的热重载影响
在开发环境下,默认修改代码后应用会自动热重启,这时候单例里的数据会被清空。如果是测试跨请求共享数据,要么别改代码,要么暂时关闭热重载试试。
按照上面的步骤排查下来,大概率就能解决问题了——只要保证是构造函数注入的单例,且应用没有意外重启,数据肯定能在跨请求之间正常共享。
内容的提问来源于stack exchange,提问作者Simon

