ASP.NET Core 6中Autofac在Main方法解析服务实例失败的解决方法
在ASP.NET Core 6的Program.cs的Main方法中,尝试使用Autofac获取服务实例,示例代码如下:
public static void Main(string[] args) { var host = Host.CreateDefaultBuilder(args) .UseServiceProviderFactory(new AutofacServiceProviderFactory()) .ConfigureWebHostDefaults(conf => { conf.UseStartup<StartupBuild>(); }) .Build(); var serviceInstance = host.Services.GetService<ISomeService>(); }
其中ISomeService已在StartupBuild类的ConfigureServices方法中通过services.TryAddTransient注册。现在遇到问题:serviceInstance无法被解析,触发以下错误:
System.ArgumentNullException: "Value cannot be null. Arg_ParamName_Name"
移除.UseServiceProviderFactory(new AutofacServiceProviderFactory())代码行后,ISomeService可成功解析。请问使用Autofac时的正确做法是什么?
出现该问题的核心原因是:使用Autofac作为服务提供工厂时,host.Services是根服务提供程序的包装器,并非直接指向Autofac容器,直接调用GetService会导致解析异常。正确做法需通过Autofac容器来获取服务,具体步骤如下:
改用Autofac容器解析服务
构建Host后,先从Host中获取Autofac的根容器,再通过容器解析服务。修改代码如下:public static void Main(string[] args) { var host = Host.CreateDefaultBuilder(args) .UseServiceProviderFactory(new AutofacServiceProviderFactory()) .ConfigureWebHostDefaults(conf => { conf.UseStartup<StartupBuild>(); }) .Build(); // 获取Autofac根容器 var autofacContainer = host.Services.GetRequiredService<ILifetimeScope>(); // 从Autofac容器解析服务 var serviceInstance = autofacContainer.Resolve<ISomeService>(); }确保Autofac整合配置正确
若StartupBuild类未重写ConfigureContainer方法,Autofac会自动导入ConfigureServices中注册的服务,但为了更清晰地控制Autofac注册逻辑,建议显式实现该方法:public class StartupBuild { public void ConfigureServices(IServiceCollection services) { // 保留原有ASP.NET Core风格的注册 services.TryAddTransient<ISomeService, SomeService>(); } // 显式实现Autofac的容器配置方法 public void ConfigureContainer(ContainerBuilder builder) { // 可添加Autofac专属注册逻辑,比如批量注册、属性注入配置等 // builder.RegisterType<SomeService>().As<ISomeService>().InstancePerDependency(); } }注意服务生命周期一致性
确保注册的服务生命周期(Transient/Scoped/Singleton)和解析方式匹配,比如Scoped服务不能直接从根容器解析,需创建子生命周期域:using(var scope = autofacContainer.BeginLifetimeScope()) { var scopedService = scope.Resolve<IScopedService>(); // 使用服务 }
内容的提问来源于stack exchange,提问作者Sven

