.NET 6 API中Autofac依赖注入失败:无法解析IProductService
.NET 6 Autofac依赖注入失败问题修复
问题场景
在.NET 6中配置Autofac依赖注入后,调用API接口时抛出服务无法解析异常,提示无法找到IProductService的注册实例以激活ProductsController。此前在低版本.NET的Startup类配置方式下可正常运行,现需适配.NET 6的顶级语句模式修复该问题。
定义的Autofac模块
public class AutofacBusinessModule:Module { protected override void Load(ContainerBuilder builder) { builder.RegisterType<ProductManager>().As<IProductService>(); builder.RegisterType<EfProductDal>().As<IProductDal>(); builder.RegisterType<CategoryManager>().As<ICategoryService>(); builder.RegisterType<EfCategoryDal>().As<ICategoryDal>(); builder.RegisterType<CustomerManager>().As<ICustomerService>(); builder.RegisterType<EfCustomerDal>().As<ICustomerDal>(); builder.RegisterType<RegionManager>().As<IRegionService>(); builder.RegisterType<EfRegionDal>().As<IRegionDal>(); builder.RegisterType<TerritoryManager>().As<ITerritoryService>(); builder.RegisterType<EfTerritoryDal>().As<ITerritoryDal>(); builder.RegisterType<ShipperManager>().As<IShipperService>(); builder.RegisterType<EfShipperDal>().As<IShipperDal>(); // 此处存在注册错误:EmployeeManager应映射到IEmployeeService而非IEmployeeDal builder.RegisterType<EmployeeManager>().As<IEmployeeDal>(); builder.RegisterType<EfEmployeeDal>().As<IEmployeeDal>(); var assembly = System.Reflection.Assembly.GetExecutingAssembly(); builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces() .EnableInterfaceInterceptors(new ProxyGenerationOptions() { Selector = new AspectInterceptorSelector() }).SingleInstance(); } }
API控制器代码
[Route("api/[controller]")] [ApiController] public class ProductsController : Controller { private readonly IProductService _productService; public ProductsController(IProductService productService) { _productService = productService; } [HttpGet("getall")] public IActionResult GetAllProducts() { var result = _productService.GetAll(); if (result.Success) { return Ok(result); } return BadRequest(result); } }
原Program.cs配置(未生效)
IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .UseServiceProviderFactory(new AutofacServiceProviderFactory()) .ConfigureContainer<ContainerBuilder>(builder => { builder.RegisterModule(new AutofacBusinessModule()); });
抛出的异常信息
System.InvalidOperationException: Unable to resolve service for type 'TAO.Business.Abstract.IProductService' while attempting to activate 'TAO.WebApi.Controllers.ProductsController'. at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired) at lambda_method3(Closure , IServiceProvider , Object[] ) at Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider.<>c__DisplayClass7_0.<CreateActivator>b__0(ControllerContext controllerContext) 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.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
请求头信息
Accept: /
Connection: keep-alive
Host: localhost:7019
User-Agent: PostmanRuntime/7.30.0
Accept-Encoding: gzip, deflate, br
Postman-Token: fbff062e-ca49-4f37-afc5-e8785afbd43c
修复步骤
1. 修正Program.cs的Autofac配置方式
.NET 6采用顶级语句模式,需通过WebApplication.CreateBuilder生成的builder.Host来配置Autofac,确保配置与Web应用生命周期绑定:
var builder = WebApplication.CreateBuilder(args); // 配置Autofac作为服务提供工厂 builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()); // 注册自定义Autofac模块 builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder => { containerBuilder.RegisterModule(new AutofacBusinessModule()); }); // 添加控制器服务(必须保留,确保控制器被正确发现) builder.Services.AddControllers(); var app = builder.Build(); // 中间件配置 app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
2. 修复模块中的注册错误
修正EmployeeManager的接口映射错误,避免服务注册冲突:
// 原错误代码 // builder.RegisterType<EmployeeManager>().As<IEmployeeDal>(); // 修正后 builder.RegisterType<EmployeeManager>().As<IEmployeeService>(); builder.RegisterType<EfEmployeeDal>().As<IEmployeeDal>();
3. 解决手动注册与自动注册的冲突
模块中同时存在手动注册和程序集自动注册,可能导致生命周期或映射关系冲突:
- 方案一:移除所有手动注册代码,完全依赖程序集扫描(需确保所有服务类都实现了对应接口,且在扫描范围内)
- 方案二:在自动注册时排除已手动注册的类型:
var assembly = System.Reflection.Assembly.GetExecutingAssembly(); builder.RegisterAssemblyTypes(assembly) .Where(t => !new[] { nameof(ProductManager), nameof(CategoryManager), nameof(EmployeeManager) }.Contains(t.Name)) .AsImplementedInterfaces() .EnableInterfaceInterceptors(new ProxyGenerationOptions() { Selector = new AspectInterceptorSelector() }).SingleInstance();
4. 确保程序集扫描范围正确
如果服务类(如ProductManager)不在WebApi项目程序集中,需指定对应类库的程序集:
// 替换为实际业务层、数据访问层的程序集名称 var businessAssembly = System.Reflection.Assembly.Load("TAO.Business"); var dataAssembly = System.Reflection.Assembly.Load("TAO.DataAccess"); builder.RegisterAssemblyTypes(businessAssembly, dataAssembly) .AsImplementedInterfaces() .EnableInterfaceInterceptors(new ProxyGenerationOptions() { Selector = new AspectInterceptorSelector() }).SingleInstance();
内容的提问来源于stack exchange,提问作者moongazing
相关产品推荐
相关产品推荐

