依赖注入:如何在Blazor应用API控制器中访问依赖项
Blazor应用API控制器中访问依赖注入项的实现方法
Blazor本身基于ASP.NET Core构建,API控制器的依赖注入逻辑和普通ASP.NET Core Web API完全一致,不需要针对Blazor做特殊适配,具体可通过以下两种常用方式实现:
1. 构造函数注入(官方推荐首选方式)
这是最稳妥的注入方式,和组件中用[Inject]特性注入的效果一致,你只需要在控制器的构造函数中声明所需依赖的类型,DI容器会在控制器实例化时自动完成解析赋值。
示例代码:
[ApiController] [Route("api/[controller]")] public class TodoController : ControllerBase { // 声明依赖的服务字段 private readonly ITodoService _todoService; // 构造函数传入依赖,容器自动解析 public TodoController(ITodoService todoService) { _todoService = todoService; } [HttpGet] public async Task<IActionResult> GetAll() { var todoList = await _todoService.GetListAsync(); return Ok(todoList); } }
2. Action参数内直接解析(适合单接口使用依赖的场景)
如果某个依赖只在单个接口方法中用到,不需要在整个控制器类中共享,可以直接在Action的参数上标记[FromServices]特性,容器会在接口调用时单独解析这个依赖,不需要写构造函数赋值逻辑。
示例代码:
[HttpGet("{id}")] public async Task<IActionResult> GetSingle(int id, [FromServices] ITodoService todoService) { var todoItem = await todoService.GetByIdAsync(id); return Ok(todoItem); }
注意事项
- 基础配置检查:确保你的
Program.cs中已经添加了控制器相关服务注册和中间件配置,这是控制器能正常触发DI的前提:// 注册控制器服务 builder.Services.AddControllers(); // 其他服务注册逻辑,比如你的ITodoService注册 builder.Services.AddScoped<ITodoService, TodoService>(); var app = builder.Build(); // 其他中间件... // 映射控制器路由 app.MapControllers(); - 不要手动new控制器实例,所有控制器实例必须交给DI容器托管,手动new的实例不会触发任何依赖解析逻辑。
- 生命周期匹配:Scoped生命周期的服务(比如EF Core的DbContext)在同一次HTTP请求中,控制器和组件中解析到的是同一个实例,不要将Scoped服务注入到Singleton生命周期的服务中,会抛出生命周期校验异常。
- 不要直接在控制器中照搬组件的
[Inject]特性做属性注入,默认情况下控制器不会识别这个特性完成注入,除非你自行扩展了DI的属性注入逻辑,优先使用构造函数注入即可。
内容的提问来源于stack exchange,提问作者billsecond
相关产品推荐
相关产品推荐

