You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Microsoft.Extensions.DependencyInjection时,WPF中AddScoped与AddSingleton有何差异?

在WPF/控制台应用中使用Microsoft.Extensions.DependencyInjection时AddScoped与AddSingleton的差异

核心本质差异

  • AddSingleton:注册的服务实例是全局单例——整个应用运行期间只会被创建一次,无论从哪个服务提供者获取,拿到的都是同一个实例,直到应用退出才会被销毁。
    比如你代码里两次写services.AddSingleton<MainViewModel>(),实际没有任何差异:DI容器只会保留最后一次的注册条目,但最终生成的实例仍然是全局唯一的。

  • AddScoped:服务实例的生命周期绑定到服务作用域(IServiceScope)。在Web应用中,每个HTTP请求会自动创建一个作用域,所以Scoped服务在单个请求内是单例;但在WPF/控制台这类没有自动请求作用域的场景下:

    • 如果直接从根服务提供者(也就是你代码里serviceProvider.GetService<MainWindow>()这种方式)获取Scoped服务,根提供者本身相当于一个全局作用域,此时Scoped服务的行为和Singleton完全一致——全程只有一个实例。
    • 只有当你手动创建局部作用域时,Scoped的特性才会体现:
      using var scope = serviceProvider.CreateScope();
      var scopedWindow = scope.ServiceProvider.GetService<MainWindow>();
      
      这种情况下,每个IServiceScope内会创建唯一的Scoped服务实例,当作用域被销毁(using块结束)时,实例也会被释放。

结合你的代码分析

你代码里同时注册了AddSingleton<MainWindow>()和AddScoped<MainWindow>(),当调用serviceProvider.GetService<MainWindow>()时,DI容器会返回最后一次注册的服务(也就是Scoped的MainWindow)。但因为是从根服务提供者获取,这个MainWindow实例的生命周期和Singleton完全一样——整个应用只会存在一个。

实际使用场景

  • 用AddSingleton存储全局共享的状态或服务(比如配置信息、全局缓存);
  • 用AddScoped处理局部生命周期的需求(比如某个业务流程内需要复用实例,流程结束后销毁资源),但必须手动创建IServiceScope才能发挥作用。

内容的提问来源于stack exchange,提问作者meJustAndrew

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 10:17:36