在 .NET Core 中,依赖注入(DI)和控制反转(IoC)的核心组件为 **IServiceCollection
** 和 **IServiceProvider
**,二者分工明确,共同实现服务的注册与解析。
一、IServiceCollection
:服务注册
-
核心职责
-
负责服务注册,定义接口与实现类的映射关系及生命周期。
-
提供扩展方法
AddTransient
、AddScoped
、AddSingleton
等,指定服务的生命周期。services.AddTransient<ILogger, FileLogger>(); // 瞬时生命周期
services.AddScoped<IDatabase, SqlDatabase>(); // 作用域生命周期
services.AddSingleton<ICache, MemoryCache>(); // 单例生命周期
-
-
生命周期类型
- Transient:每次请求创建新实例。
- Scoped:同一作用域(如 HTTP 请求)共享一个实例。
- Singleton:全局共享单个实例。
二、IServiceProvider
:服务解析
-
核心职责
-
通过
IServiceCollection.BuildServiceProvider()
构建,用于解析已注册的服务。 -
提供
GetService<T>
或GetRequiredService<T>
方法获取服务实例。var provider = services.BuildServiceProvider(); var logger = provider.GetService<ILogger>();
-
-
依赖注入实现
-
支持构造函数注入、属性注入(不推荐)等方式自动解析依赖。
-
示例 (控制器注入):
public class UserController : Controller
{
private readonly IUserService _userService;
public UserController(IUserService userService) => _userService = userService; // 自动注入
}
-
三、协作流程
- 注册阶段
- 在
Startup.ConfigureServices
中通过IServiceCollection
注册服务。
- 在
- 构建容器
- 调用
BuildServiceProvider()
生成IServiceProvider
。
- 调用
- 解析阶段
- 通过构造函数或手动从
IServiceProvider
获取服务实例。
- 通过构造函数或手动从
四、应用场景
- 解耦业务逻辑
- 通过接口抽象与实现分离,便于替换具体实现(如切换数据库、日志系统)。
- 中间件与配置集成
- 中间件通过构造函数注入服务,配置类通过
IOptions<T>
注入。
- 中间件通过构造函数注入服务,配置类通过
- 资源生命周期管理
- 合理使用生命周期避免内存泄漏(如
Scoped
生命周期释放数据库连接)。
- 合理使用生命周期避免内存泄漏(如
总结
- **
IServiceCollection
** 是依赖关系的配置入口,**IServiceProvider
** 是依赖解析的执行容器。 - 二者结合实现了控制反转(IoC)的核心思想:将依赖的创建与使用分离,提升代码的可维护性和可测试性。