依赖注入(DI)无法向控制器注入服务,求排查解决方案
问题分析与解决方案
哥们,你的问题根源出在控制器构造函数里手动创建全新的ServiceCollection容器上,这完全违背了ASP.NET Core依赖注入的设计思路,具体来说:
为什么服务会是null?
看你构造函数里的这行代码:
this.locationService = (ILocationService)new ServiceCollection().BuildServiceProvider().GetService(typeof(ILocationService));
你在这里新建了一个ServiceCollection并构建了一个全新的服务提供者,这个容器和你在Startup.ConfigureServices里注册服务的容器完全是两个独立的实例,里面根本没有你注册的ILocationService和其他服务,所以调用GetService自然返回null。
而且这种做法还会导致重复创建服务实例、资源浪费,甚至可能引发生命周期管理的问题,绝对是要避免的。
正确的解决方式:使用构造函数注入
ASP.NET Core的DI容器会自动帮你解析并注入所需的服务,你只需要把ILocationService直接加到控制器的构造函数参数里就行,不需要手动去获取。修改你的SuggestController如下:
public class SuggestController { readonly ILocationService locationService; // 直接将ILocationService加入构造函数参数 public SuggestController( IOptions<SiteSettings> settings, IOptions<DBAccessBuilder> access, IStringLocalizer<SharedResources> localizer, IMemoryCache memoryCache, IHostingEnvironment environment, ILocationService locationService) // 新增这一行 { this.locationService = locationService; // 直接赋值 } }
额外需要确认的点
还要检查LocationService依赖的ISolrOperations<LocationResult>是否已经在Startup.ConfigureServices中注册了!因为如果这个服务没注册,DI容器在解析ILocationService的时候会抛出异常,比如需要添加类似这样的代码:
services.AddSingleton<ISolrOperations<LocationResult>, YourSolrImplementation>();
确保所有依赖链上的服务都完成注册,DI容器才能正常解析。
总结一下正确步骤
- 所有需要注入的服务(包括底层依赖)都在
Startup.ConfigureServices中完成注册 - 控制器/服务通过构造函数参数声明所需服务,由DI容器自动注入,不要手动创建ServiceProvider
内容的提问来源于stack exchange,提问作者Coder
相关产品推荐
相关产品推荐

