ASP.NET Core控制器DI无法解析IBookService服务报错解决
错误根因
你的判断完全准确。该System.InvalidOperationException的触发原因是ASP.NET Core依赖注入容器未找到Core.Interfaces.IBookService对应的注册映射:容器激活BookController时,会递归解析构造函数声明的所有依赖参数,未查询到指定服务类型的注册项时就会抛出无法解析服务的异常,和你采用常规REST Controller、三层架构的实现方案无关。
修复步骤
- 先确认基础引用配置:API层已添加对Core层的项目引用,确保Program.cs中可以访问到
Core.Interfaces.IBookService和Core.Services.BookService两个类型,缺少引用会直接触发编译错误。 - 在Program.cs的服务注册区块(即调用
builder.Build()之前的代码段),添加服务映射注册,和你已完成的泛型仓储、日志、内存数据库、控制器服务注册放在同一区域即可。参考常规分层架构默认的Scoped生命周期(每个HTTP请求生成一个服务实例,请求结束后释放,是Web业务服务的默认推荐选择),注册代码如下:
生命周期选择说明:builder.Services.AddScoped<IBookService, BookService>();- 不要选择
AddSingleton:单例生命周期会导致服务持有的DbContext长期驻留,极易出现数据库上下文并发冲突、脏数据问题 - 有特殊轻量无状态需求时可以选择
AddTransient,每次注入请求都会生成新的服务实例,但常规业务场景优先用AddScoped,和你已注册的泛型仓储、内存数据库上下文生命周期保持一致,避免依赖链生命周期不匹配的问题。
- 不要选择
- 注册顺序无强制要求,只要在
builder.Build()执行前完成注册即可,建议按依赖层级从底到顶注册:先注册基础设施层组件(DbContext、日志、泛型仓储),再注册核心业务服务(如IBookService),最后注册控制器、接口文档等上层组件,代码结构更易维护。
验证逻辑
注册完成后重启应用,DI容器会按依赖链完成所有组件的解析:
- 激活BookController时,识别到需要IBookService参数,匹配到注册的BookService实现
- 解析BookService时,识别到其依赖的
IRepository<Book>、IAppLogger<BookService>已经完成注册,自动生成对应实例 - 所有依赖满足后,BookController实例正常创建,
/api/Book路由即可正常响应请求
架构提示:保留服务层作为控制器和仓储的中间层是符合分层架构规范的设计,不要为了快速修复直接让控制器注入仓储,避免业务逻辑散落在控制器中,否则后续维护、单元测试的成本会大幅升高。
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

