C#的依赖注入(DI)是一种实现控制反转(IoC)的设计模式,核心思想是将对象的依赖关系由外部容器来管理和注入,而不是在对象内部自行创建依赖实例。这种方式可以让代码组件之间的耦合度大幅降低,后续修改依赖实现或者进行单元测试时都会更加方便。ASP.NET Core从框架层面内置了依赖注入容器,开发者不需要引入额外的第三方库就可以直接使用相关功能。

依赖注入的核心概念
依赖注入主要包含三个角色:服务(被依赖的组件)、服务容器(管理服务的注册和生命周期)、消费者(需要使用服务的组件)。在ASP.NET Core中,服务容器由IServiceProvider接口表示,服务的注册和配置通过IServiceCollection接口完成。
常见的依赖注入方式有三种:
- 构造函数注入:通过消费者的构造函数传入依赖的服务,是ASP.NET Core中最推荐的使用方式
- 属性注入:通过公共属性设置依赖的服务,ASP.NET Core默认不支持,需要额外配置
- 方法注入:通过方法的参数传入依赖的服务,适合临时使用某个依赖的场景
ASP.NET Core中配置依赖注入的步骤
1. 定义服务接口和实现类
首先我们需要定义一个需要被注入的服务,通常先定义接口,再实现具体的类,这样后续可以方便地替换实现。
// 定义服务接口
public interface IUserService
{
string GetUserName(int userId);
}
// 实现服务接口
public class UserService : IUserService
{
public string GetUserName(int userId)
{
// 模拟从数据库获取用户名称的逻辑
return $"用户{userId}";
}
}
2. 在Program.cs中注册服务
ASP.NET Core的服务注册都在Program.cs文件的构建主机过程中完成,通过IServiceCollection的扩展方法来添加服务。服务的生命周期有三种可选,开发者需要根据实际场景选择:
| 生命周期 | 说明 |
|---|---|
| Transient | 每次请求服务时都会创建一个新的实例,适合轻量级的、无状态的服务 |
| Scoped | 在同一个请求范围内,多次获取服务会返回同一个实例,适合需要保持请求内状态的服务 |
| Singleton | 整个应用程序生命周期内只会创建一个实例,适合全局共享的服务 |
注册服务的代码示例如下:
var builder = WebApplication.CreateBuilder(args); // 注册服务,这里选择Transient生命周期 builder.Services.AddTransient<IUserService, UserService>(); // 也可以注册其他框架内置的服务,比如控制器 builder.Services.AddControllers(); var app = builder.Build(); // 配置中间件 app.MapControllers(); app.Run();
3. 在组件中注入服务
ASP.NET Core中控制器、页面模型、中间件等组件都支持构造函数注入,只需要在构造函数中声明对应的服务类型作为参数即可,容器会自动解析并传入实例。
控制器中注入服务的示例:
[ApiController]
[Route("api/[controller]")]
public class UserController : ControllerBase
{
private readonly IUserService _userService;
// 构造函数注入,容器会自动传入IUserService的实例
public UserController(IUserService userService)
{
_userService = userService;
}
[HttpGet("{id}")]
public string GetUserName(int id)
{
return _userService.GetUserName(id);
}
}
注意事项
在使用依赖注入时需要注意几个问题:
- 避免循环依赖,即A依赖B,B又依赖A,这种情况会导致容器解析失败抛出异常
- 合理选择服务的生命周期,比如如果服务依赖了Scoped生命周期的组件,那么服务本身也应该是Scoped或者更短的生命周期,否则会出现作用域问题
- 不要手动new依赖的服务实例,而是通过容器注入,否则会失去依赖注入的优势
依赖注入并不是ASP.NET Core独有的功能,普通的C#控制台程序也可以通过引入Microsoft.Extensions.DependencyInjection包来使用依赖注入容器,使用方式和ASP.NET Core中的配置逻辑基本一致。
依赖注入ASP.NET_CoreIServiceCollectionServiceLifetime构造函数注入修改时间:2026-06-19 12:09:28