.NET 8 Web API依赖注入错误:无法解析ICommanderRepo服务
问题:ASP.NET Core Web API依赖注入失败,无法解析ICommanderRepo服务
发送GET请求时触发异常,错误信息如下:
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware
执行请求时发生未处理的异常。
System.InvalidOperationException: 尝试激活'Commander.Controllers.CommandsController'时无法解析'Commander.Data.ICommanderRepo'类型的服务
相关代码
CommandsController.cs
namespace Commander.Controllers { // Api/commands [Route("api/commands")] [ApiController] public class CommandsController : ControllerBase { private readonly ICommanderRepo _repository; //Dependency injected value public CommandsController(ICommanderRepo repository) //Inject dependency { _repository = repository; } //private readonly MockCommanderRepo _repository = new MockCommanderRepo(); //GET api/commands [HttpGet] public ActionResult <IEnumerable<Command>> GetAllCommands() { var commandItems = _repository.GetAppCommands(); return Ok(commandItems); } //GET api/commands/{id} [HttpGet("{id}")] public ActionResult <Command> GetCommandById(int id) { var commandItem = _repository.GetCommandById(id); return Ok(commandItem); } } }
ICommanderRepo.cs
namespace Commander.Data { public interface ICommanderRepo { IEnumerable<Command> GetAppCommands(); Command GetCommandById(int id); } }
MockCommanderRepo.cs
namespace Commander.Data { public class MockCommanderRepo : ICommanderRepo { public IEnumerable<Command> GetAppCommands() { var commands = new List<Command> { new Command{Id=0, HowTo="Boil an egg", Line="Boil water", Platform="Kettle & Pan"}, new Command{Id=1, HowTo="Cut bread", Line="Get a knife", Platform="Knife & chopping board"}, new Command{Id=2, HowTo="Make cup of tea", Line="Place teabag in cup", Platform="Kettle & cup"} }; return commands; } public Command GetCommandById(int id) { return new Command{Id=0, HowTo="Boil an egg", Line="Boil water", Platform="Kettle & Pan"}; } } }
Command.cs
namespace Commander.Models { public class Command { public int Id { get; set; } public string HowTo { get; set; } = default!; public string Line { get; set; } = default!; public string Platform { get; set; } = default!; } }
Startup.cs
namespace Commander { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddScoped<ICommanderRepo, MockCommanderRepo>(); //Dependency injection } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } }
Program.cs
var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
问题原因
你使用的是.NET 8,而.NET 6及以后版本默认采用顶级语句的Program.cs作为启动入口,不再自动调用Startup类的ConfigureServices和Configure方法。你在Startup.cs中注册的依赖注入服务根本没有被执行,所以DI容器找不到ICommanderRepo的实现。
解决方法
将依赖注入注册代码移到Program.cs的服务配置部分,修改后的Program.cs如下:
var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); // 注册ICommanderRepo的实现 builder.Services.AddScoped<Commander.Data.ICommanderRepo, Commander.Data.MockCommanderRepo>(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
或者,如果你想继续使用Startup类,需要在Program.cs中显式调用Startup的配置方法:
var builder = WebApplication.CreateBuilder(args); var startup = new Startup(builder.Configuration); startup.ConfigureServices(builder.Services); var app = builder.Build(); startup.Configure(app, app.Environment); app.Run();
推荐第一种方案,符合.NET 6+的官方推荐写法。
内容的提问来源于stack exchange,提问作者Clarissa
相关产品推荐
相关产品推荐

