.NET Core 7.0 WinForms中HttpClient依赖注入为空,如何实现单例注入?
Windows Forms中通过依赖注入获取HttpClient单例实例的解决方案
问题根源
- 默认.NET DI容器不识别
[Inject]属性,不会自动完成属性注入 - 即便支持属性注入,构造函数执行时属性注入尚未完成,此时访问属性会返回null
方案1:构造函数注入(推荐)
这是依赖注入的标准实现方式,能保证实例初始化时依赖已就绪,避免空引用问题。
修改Form1代码:
public partial class Form1 : Form { private readonly HttpClient _http; // 通过构造函数接收HttpClient实例 public Form1(HttpClient http) { _http = http; InitializeComponent(); System.Diagnostics.Debug.WriteLine(_http == null); // 输出False } }
你的Program.cs代码无需修改,AddHttpClient()已经完成了HttpClient的注册,DI容器会自动解析并将实例传入Form1的构造函数。
方案2:属性注入(需手动配置)
如果必须使用属性注入,需要手动让DI容器处理属性注入逻辑,且不能在构造函数内访问注入的属性。
步骤1:修改Program.cs,添加属性注入逻辑
[STAThread] static void Main() { ApplicationConfiguration.Initialize(); var services = new ServiceCollection(); services.AddHttpClient(); services.AddScoped<Form1>(); using (ServiceProvider serviceProvider = services.BuildServiceProvider()) { var form1 = serviceProvider.GetRequiredService<Form1>(); // 手动处理[Inject]属性的注入 foreach (var prop in typeof(Form1).GetProperties() .Where(p => p.GetCustomAttribute<InjectAttribute>() != null)) { var service = serviceProvider.GetService(prop.PropertyType); prop.SetValue(form1, service); } Application.Run(form1); } }
步骤2:修改Form1,在合适时机访问属性
public partial class Form1 : Form { [Inject] public HttpClient? http { get; set; } public Form1() { InitializeComponent(); // 构造函数内http仍为null,不要在此访问 } private void Form1_Load(object sender, EventArgs e) { // 窗体加载时属性已完成注入 System.Diagnostics.Debug.WriteLine(http == null); // 输出False } }
注意:属性注入无法保证依赖的完整性,存在空引用风险,优先推荐使用构造函数注入。
内容的提问来源于stack exchange,提问作者Matias Masso
相关产品推荐
相关产品推荐

