ASP.NET WebForms 4.7.2实现IHttpClientFactory时注入对象为null
问题根因
_mymanager字段为null是三个核心配置错误导致的:
- 同时维护了Unity和.NET Generic Host两套完全独立的DI容器,服务注册没有打通:
AddHttpClient()注入的IHttpClientFactory实例存在于Host生成的容器中,而自定义的IHttpClientFactoryProvider、IMyanager注册在Unity容器内,Unity既无法解析IHttpClientFactory依赖,也没有和ASP.NET WebForms的页面实例化流程做集成。 - ASP.NET WebForms默认通过无参构造函数反射创建页面实例,你定义的带
IMyanager参数的构造函数不会被默认逻辑调用,运行时会命中你写的空无参构造,_mymanager自然不会被赋值。 - 静态字段存储的Host容器
ServiceProvider既没有和Unity做服务互通,也没有被配置为WebForms的默认服务提供器,整个DI链路在页面激活层是断开的。
解决步骤
1. 整合DI容器,移除重复注册
不要维护两套独立容器,直接将所有服务注册统一到Generic Host的IServiceCollection中,如果需要继续使用Unity作为底层容器,安装对应适配包即可,修改Global.asax代码如下:
public static IServiceProvider ServiceProvider; void Application_Start(object sender, EventArgs e) { var hostBuilder = new HostBuilder(); // 如需保留Unity作为底层容器,安装Unity.Microsoft.DependencyInjection包后取消下一行注释 // hostBuilder.UseUnityServiceProvider(); hostBuilder.ConfigureServices(ConfigureServices); var host = hostBuilder.Build(); ServiceProvider = host.Services; // 原有启动逻辑保持不变 RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); } void ConfigureServices(IServiceCollection services) { // 注册HttpClientFactory相关服务 services.AddHttpClient(); // 注册自定义服务,生命周期根据业务需求选择Transient/Scoped/Singleton services.AddTransient<IHttpClientFactoryProvider, HttpClientFactoryProvider>(); services.AddTransient<IMyanager, MyManager>(); }
2. 配置WebForms使用DI容器激活页面
.NET Framework 4.7.2及以上版本原生支持DI集成,只需要在Global.asax中重写服务获取方法,让WebForms运行时从我们配置好的容器中解析页面、控件等类型实例:
public override object GetService(Type serviceType) { return ServiceProvider.GetService(serviceType); }
同时修改Default.aspx后台代码,删除空的无参构造函数,避免运行时绕过DI逻辑:
public partial class _Default : Page { private readonly IMyanager _mymanager; public _Default(IMyanager mymanager) { _mymanager = mymanager; } protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { var result = _mymanager.GetData(); } } }
校验排查点
修改完成后按以下顺序验证配置正确性:
- 确认项目已安装
Microsoft.Extensions.Http包,.NET Framework 4.7.2环境下建议选择6.x及以下LTS版本,避免高版本依赖出现兼容性问题 - 调试时在
Application_Start执行完成后加断点,直接调用ServiceProvider.GetService<IMyanager>(),如果能正常返回实例说明容器配置正确,如果抛出异常优先解决服务注册的依赖问题 - 确认Global.asax中重写的
GetService方法签名完全匹配(public override,参数为Type类型),拼写错误会导致WebForms运行时无法识别该扩展点 - 所有依赖链路中的类型不要手动通过
new关键字创建,必须通过容器解析,否则DI链路会断开,依然会出现空引用问题
内容的提问来源于stack exchange,提问作者eljallouly
相关产品推荐
相关产品推荐

