依赖注入注入的Info类属性跨控制器访问始终为null是什么原因?
错误原因
- 实例替换操作错误
你在Subscription控制器的Get方法中直接new Info()赋值给控制器的Info字段,等于直接丢弃了DI容器注入的原有实例,你赋值的只是当前控制器的本地变量,DI容器中注册的实例不会同步修改,其他类注入拿到的还是初始的空实例。正确做法是直接修改注入实例的属性,而非重新实例化。 - 服务生命周期不匹配需求
你当前用AddScoped<Info>()注册的服务生命周期是「请求级别」:每次新的HTTP请求都会创建一个全新的Info实例。你调用第一个控制器赋值是一次请求,调用第二个控制器取值是另一次独立请求,两次请求拿到的本来就不是同一个实例,自然拿不到赋值后的属性。
如果需要跨所有请求全局共享同一个Info实例,应该注册为单例:services.AddSingleton<Info>();如果仅需同一次请求内跨服务共享,保留Scoped即可,但是不能跨请求使用。 - 额外的语法错误
你控制器中定义的私有字段是小写info,构造函数中给this.Info赋值,大小写不匹配会导致私有字段没有被正确赋值,后续操作的可能是未初始化的变量,需要统一大小写。
修正后的代码示例
Startup.cs 服务注册(全局共享场景)
public void ConfigureServices(IServiceCollection services) { //.... services.AddScoped<IFileService, FileService>(); // 注册为单例,全局共享同一个实例 services.AddSingleton<Info>(); //... }
SubscriptionController 赋值逻辑修正
private Info info; public SubscriptionController(Info info) { // 统一大小写,正确给私有字段赋值 this.info = info; } [HttpGet] public async Task<ActionResult<string>> Get(string driveId, string itemId, string pdfItemId, int subscriptionTime) { //...... // 直接修改注入实例的属性,不重新new info.DriveId = driveId; info.ItemId = itemId; info.SubscriptionTime = subscriptionTime; info.PdfItemId = pdfItemId; //...... }
注意事项
如果是多用户使用的服务,全局单例的Info会被所有用户共享,存在数据互相覆盖的线程安全问题,这种场景建议将Info存到用户会话、数据库或者缓存中,不要用全局单例。
内容的提问来源于stack exchange,提问作者ChsharpNewbie
相关产品推荐
相关产品推荐

