.NET Core 7.0依赖注入报错:无法解析IRepository服务
.NET Core 7.0微服务依赖注入问题排查
问题现象
项目启动时触发依赖注入解析失败错误:
System.InvalidOperationException: Unable to resolve service for type 'Marketmax.Common.IRepository`1[Marketmax.Service.Entities.ServiceEntity]' while attempting to activate 'Marketmax.MicroService.Controllers.ServicesController'.
相关代码片段
Program.cs配置
// Configure services builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.AddMongo(configuration); // MongoDB初始化 builder.Services.AddMongoRepository<ServiceEntity>("Services"); // 问题触发点 builder.Services.AddScoped<ServicesController>();
ServicesController实现
namespace Marketmax.MicroService.Controllers { [ApiController] [Route("services")] public class ServicesController : ControllerBase { private readonly IRepository<ServiceEntity> _repository; public ServicesController(IRepository<ServiceEntity> repository) { _repository = repository; } // ... 控制器操作方法 } }
NuGet包中的IRepository接口
public interface IRepository<T> where T : IServiceEntity { Task<IReadOnlyCollection<T>> GetAllAsync(); Task<IReadOnlyCollection<T>> GetAllAsync(Expression<Func<T, bool>> filter); Task CreateAsync(T entity); Task<T> GetAsync(Guid id); Task<T> GetAsync(Expression<Func<T, bool>> filter); Task RemoveAsync(Guid id); Task UpdateAsync(T entity); }
NuGet包中的Mongo扩展方法
public static class MongoExtension { public static IServiceCollection AddMongo(this IServiceCollection services, IConfiguration configuration) { IConfiguration configuration2 = configuration; BsonSerializer.RegisterSerializer(new GuidSerializer(BsonType.String)); BsonSerializer.RegisterSerializer(new DateTimeSerializer(BsonType.String)); services.AddSingleton(delegate { ServiceSettings serviceSettings = configuration2.GetSection("ServiceSettings").Get<ServiceSettings>(); MongoDbSettings mongoDbSettings = configuration2.GetSection("MongoDbSettings").Get<MongoDbSettings>(); MongoClient mongoClient = new MongoClient(mongoDbSettings.ConnectionString); return mongoClient.GetDatabase(serviceSettings.ServiceName); }); return services; } public static IServiceCollection AddMongoRepository<T>(this IServiceCollection services, string collectionName) where T : IServiceEntity { string collectionName2 = collectionName; services.AddSingleton((Func<IServiceProvider, IRepository<IServiceEntity>>)delegate (IServiceProvider serviceProvider) { IMongoDatabase service = serviceProvider.GetService<IMongoDatabase>(); return new MongoRepository<IServiceEntity>(service, collectionName2); }); return services; } }
完整错误栈
System.InvalidOperationException: Unable to resolve service for type 'Marketmax.Common.IRepository`1[Marketmax.Service.Entities.ServiceEntity]' while attempting to activate 'Marketmax.MicroService.Controllers.ServicesController'. at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired) at lambda_method9(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.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger) at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context) at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext) at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider) at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
问题根源
AddMongoRepository<T>方法中注册的是IRepository<IServiceEntity>类型实例,但控制器依赖的是IRepository<ServiceEntity>。由于泛型接口未声明协变(且接口包含输入参数的方法,无法声明协变),DI容器无法将IRepository<IServiceEntity>自动转换为IRepository<ServiceEntity>。
修复方案
1. 修改扩展方法注册逻辑
调整AddMongoRepository<T>,注册与泛型参数T匹配的IRepository<T>类型:
public static class MongoExtension { // 保留AddMongo方法不变 public static IServiceCollection AddMongoRepository<T>(this IServiceCollection services, string collectionName) where T : IServiceEntity { services.AddSingleton<IRepository<T>>(serviceProvider => { var database = serviceProvider.GetService<IMongoDatabase>(); return new MongoRepository<T>(database, collectionName); }); return services; } }
2. 修正MongoRepository实现
确保MongoRepository<T>直接实现IRepository<T>,而非IRepository<IServiceEntity>:
public class MongoRepository<T> : IRepository<T> where T : IServiceEntity { private readonly IMongoCollection<T> _collection; public MongoRepository(IMongoDatabase database, string collectionName) { _collection = database.GetCollection<T>(collectionName); } // 实现IRepository<T>的所有方法... }
3. 移除冗余控制器注册
删除builder.Services.AddScoped<ServicesController>(),因为AddControllers()已经自动完成所有控制器的注册,手动注册可能导致生命周期冲突。
内容的提问来源于stack exchange,提问作者Berlin Johns. M
相关产品推荐
相关产品推荐

