ASP.NET Core依赖注入报错:无法解析CourseAPIController服务
解决ASP.NET Core中无法注入API控制器到MVC控制器的问题
你遇到的InvalidOperationException是因为ASP.NET Core的DI容器默认不会将控制器类型注册为可注入服务,直接在CoursePageController构造函数中注入CourseAPIController会导致容器无法解析该类型。以下是几种符合扩展性要求的解决方案:
方案1:提取业务逻辑到独立服务层(推荐)
将课程CRUD逻辑从API控制器抽离到独立服务类,让MVC控制器和API控制器共同依赖该服务,彻底解耦两者的依赖关系,符合SOLID原则。
步骤:
- 定义服务接口:
public interface ICourseService { IEnumerable<Course> ListCourses(string searchKey = null); // 添加其他CRUD方法声明 }
- 实现服务类:
public class CourseService : ICourseService { private readonly AppDbContext _dbContext; public CourseService(AppDbContext dbContext) { _dbContext = dbContext; } public IEnumerable<Course> ListCourses(string searchKey = null) { var query = _dbContext.Courses.AsQueryable(); if (!string.IsNullOrEmpty(searchKey)) { query = query.Where(c => c.Name.Contains(searchKey) || c.Code.Contains(searchKey)); } return query.ToList(); } // 实现其他CRUD方法 }
- 注册服务到DI容器:
在Program.cs中添加:
builder.Services.AddScoped<ICourseService, CourseService>();
- 修改API控制器依赖服务:
[ApiController] [Route("api/[controller]")] public class CourseAPIController : ControllerBase { private readonly ICourseService _courseService; public CourseAPIController(ICourseService courseService) { _courseService = courseService; } [HttpGet("list")] public IActionResult ListCourses(string searchKey = null) { var courses = _courseService.ListCourses(searchKey); return Ok(courses); } }
- 修改MVC控制器依赖服务:
public class CoursePageController : Controller { private readonly ICourseService _courseService; public CoursePageController(ICourseService courseService) { _courseService = courseService; } public IActionResult List(string SearchKey = null) { var courses = _courseService.ListCourses(SearchKey); return View(courses); } }
方案2:使用HttpClient调用API接口(跨服务场景适用)
如果需要MVC控制器通过HTTP请求调用API(比如API独立部署),可以使用HttpClient替代直接注入控制器:
- 注册HttpClient:
在Program.cs中添加:
builder.Services.AddHttpClient("CourseApi", client => { client.BaseAddress = new Uri(builder.Configuration["ApiBaseUrl"] ?? "https://localhost:5001/api/"); });
- 修改MVC控制器调用API:
public class CoursePageController : Controller { private readonly IHttpClientFactory _httpClientFactory; public CoursePageController(IHttpClientFactory httpClientFactory) { _httpClientFactory = httpClientFactory; } public async Task<IActionResult> List(string SearchKey = null) { var client = _httpClientFactory.CreateClient("CourseApi"); var courses = await client.GetFromJsonAsync<IEnumerable<Course>>($"course/list?SearchKey={SearchKey}"); return View(courses); } }
方案3:手动注册API控制器到DI容器(不推荐)
虽然可以强制将API控制器注册到DI容器,但这种做法违背控制器的职责设计,会提高代码耦合度,仅作为临时 workaround:
在Program.cs中添加:
builder.Services.AddScoped<CourseAPIController>();
内容的提问来源于stack exchange,提问作者Wyatt Onscroll
相关产品推荐
相关产品推荐

