ServiceCollection 和 ServiceProvider 是 .NET 依赖注入系统中的两个核心概念,但它们的职责完全不同。理解这两个概念对看懂 ASP.NET Core / ABP 框架的 DI 机制非常重要。
下面用非常清晰、分层方式给你解释:
✔️ 一句话解释
- ServiceCollection:用来“登记服务”(注册 DI 的地方),只是一本服务清单。
- ServiceProvider:用来“提供服务”(从 DI 容器中取服务),是运行中的 IoC 容器。
✔️ 详细解释:ServiceCollection
它是什么?
IServiceCollection 就是一个服务注册表,你把所有需要依赖注入的类型都注册到这里。
常见用法:
var services = new ServiceCollection();services.AddSingleton<IMyService, MyService>();
services.AddTransient<IOtherService, OtherService>();
它的本质
- 是一个 List
- 存的是“如何创建服务”的描述信息
- 不负责实例化对象
- 在 ConfigureServices() 中使用
生命周期
- 只存在初始化阶段
- ASP.NET Core 启动的时候把它填满
- 最终会被用来构建一个 ServiceProvider
✔️ 详细解释:ServiceProvider
它是什么?
IServiceProvider 才是真正的 依赖注入容器,负责:
- 解析服务(Resolve)
- 管理生命周期
- 创建对象实例
常见用法:
var provider = services.BuildServiceProvider();var myService = provider.GetRequiredService<IMyService>();
它的本质
- 根据 ServiceCollection 的描述,负责创建对象实例
- 会管理 Singleton / Scoped / Transient 的生命周期
- 是运行时一直存在的容器
- ASP.NET Core 的 Controller 等都是从这里取依赖
生命周期
- 创建后一直存在(直到程序停止)
- Web 请求期间会生成子
IServiceScope管理 Scoped 服务
✔️ ABP 和 ASP.NET 的不同点
在 ABP 里,最终 DI 容器通常是 AutoFac 或 Castle Windsor(取决于版本)
但是概念一样:
| 阶段 | 在做什么 |
|---|---|
| Startup / Module PreConfigure | 注册服务(向 ServiceCollection 加东西) |
| Application startup | 构建 ServiceProvider |
| Runtime | Controller、Service、Repository 都从 ServiceProvider 获取依赖 |
✔️ 为什么需要两者?(关键理解)
Step 1:先有服务清单(ServiceCollection)
像菜单一样,描述有哪些服务、用什么生命周期、怎么创建。
Step 2:再构建容器(ServiceProvider)
把菜单转换成真正的工厂,可以随时生产对象。
Step 3:运行期间用容器取服务
GetService() → 不报错
GetRequiredService() → 找不到会报异常
GetKeyedService() → 根据 Key 解析不同实现(.NET 7+)
✔️ 简易比喻
| 角色 | 现实中的比喻 |
|---|---|
| ServiceCollection | 菜单(描述怎么做菜) |
| ServiceProvider | 厨房(真正做菜的地方) |
| AddSingleton/AddTransient | 菜谱写法 |
| GetService/GetRequiredService | 点菜(厨房做给你) |
✔️ 简易图示
[ServiceCollection] => 服务注册阶段- IMail → MailService- IConfig → ConfigService- IOcr → BaiduOcrBuildServiceProvider()↓
[ServiceProvider] => 服务解析阶段provider.GetRequiredService<IMail>()