EF通用仓储NuGet包开发:依赖注入服务解析失败问题
错误信息
System.InvalidOperationException: Unable to resolve service for type 'Play.Catalog.Interface.IRepository`1[Play.Catalog.Service.Entities.Item]' while attempting to activate 'Play.Catlog.Service.Controller.ItemsController'.
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.ThrowHelperUnableToResolveService(Type type, Type requiredBy)
at lambda_method10(Closure, IServiceProvider, Object[])
at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass6_0.<CreateControllerFactory>g__CreateController|0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
问题原因
- 服务注册与依赖不匹配:控制器
ItemsController依赖的是IRepository<Item>,但你在Program.cs中仅注册了IRepository<IEntity>,DI容器无法将IRepository<IEntity>转换为IRepository<Item>。 - 泛型服务注册方式错误:当前注册代码仅针对
IEntity类型的仓储实例,没有使用开放泛型来支持任意实现IEntity的实体类型(比如Item)。
解决方案
修改Program.cs中的服务注册代码,将原来的单一类型注册替换为开放泛型注册,让DI容器能够为任意TEntity(实现IEntity)自动解析对应的Repository<CatalogDbContext, TEntity>实例。
修改后的Program.cs关键代码
// 替换原来的单一注册语句 builder.Services.AddScoped(typeof(IRepository<>), typeof(Repository<CatalogDbContext, <>));
完整修改后的Program.cs
using Play.Catalog.Service.Db; using Microsoft.EntityFrameworkCore; using Play.Catalog.Interface; using Play.Catalog.Repositories; using Play.Catalog.Service.Entities; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.AddControllers(); builder.Services.AddSqlServer<CatalogDbContext>(builder.Configuration.GetConnectionString("DefaultConnection")); // 正确注册开放泛型仓储服务 builder.Services.AddScoped(typeof(IRepository<>), typeof(Repository<CatalogDbContext, <>)); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.MapControllers(); app.UseDeveloperExceptionPage(); app.Run();
额外注意事项
- 检查命名空间拼写:控制器的命名空间是
Play.Catlog.Service.Controller(注意Catlog缺少一个字母a,应为Catalog),虽然这不是当前注入错误的直接原因,但长期可能导致其他问题,建议统一修正。 - 确保
Item类正确实现IEntity接口:你的代码中Item已经实现了IEntity,这部分没问题。
内容的提问来源于stack exchange,提问作者Sushil Patil

