.NET Core 1.1迁移至3.1:如何注册Autofac容器释放回调?
升级.NET Core 3.1时Autofac容器释放问题解决方法
问题背景
从.NET Core 1.1升级至3.1后,原1.1中通过appLifetime.ApplicationStopped.Register(() => this.ApplicationContainer.Dispose())实现的应用停止时Autofac容器释放逻辑,在新的Startup结构下不知如何适配。
.NET Core 1.1 原有代码
public class Startup { public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) .AddEnvironmentVariables(); this.Configuration = builder.Build(); } public IContainer ApplicationContainer { get; private set; } public IConfigurationRoot Configuration { get; private set; } public IServiceProvider ConfigureServices(IServiceCollection services) { services.AddMvc(); var builder = new ContainerBuilder(); builder.RegisterType<MyType>().As<IMyType>(); builder.Populate(services); this.ApplicationContainer = builder.Build(); return new AutofacServiceProvider(this.ApplicationContainer); } public void Configure( IApplicationBuilder app, ILoggerFactory loggerFactory, IApplicationLifetime appLifetime) { loggerFactory.AddConsole(this.Configuration.GetSection("Logging")); loggerFactory.AddDebug(); app.UseMvc(); appLifetime.ApplicationStopped.Register(() => this.ApplicationContainer.Dispose()); } }
.NET Core 3.1 当前Startup结构
public class Startup { public Startup(IConfiguration configuration) { this.Configuration = configuration; } public IConfiguration Configuration { get; private set; } public ILifetimeScope AutofacContainer { get; private set; } public void ConfigureServices(IServiceCollection services) { services.AddOptions(); } public void ConfigureContainer(ContainerBuilder builder) { builder.RegisterModule(new MyApplicationModule()); } public void Configure( IApplicationBuilder app, ILoggerFactory loggerFactory, IApplicationLifetime appLifetime) { this.AutofacContainer = app.ApplicationServices.GetAutofacRoot(); loggerFactory.AddConsole(this.Configuration.GetSection("Logging")); loggerFactory.AddDebug(); app.UseMvc(); } }
解决方案
1. 替换过时的生命周期接口
.NET Core 3.0+ 中IApplicationLifetime已被标记为过时,官方推荐使用IHostApplicationLifetime,两者事件定义一致,直接替换参数类型即可。
2. 注册容器释放逻辑
在Configure方法中,获取到Autofac根容器后,将其释放逻辑注册到应用停止事件中,和原1.1逻辑一致:
修改后的Configure方法代码:
public void Configure( IApplicationBuilder app, ILoggerFactory loggerFactory, IHostApplicationLifetime appLifetime) { this.AutofacContainer = app.ApplicationServices.GetAutofacRoot(); loggerFactory.AddConsole(this.Configuration.GetSection("Logging")); loggerFactory.AddDebug(); app.UseMvc(); // 注册应用停止时的容器释放逻辑 appLifetime.ApplicationStopped.Register(() => this.AutofacContainer.Dispose()); }
补充说明
实际上,使用Autofac官方的.NET Core集成包时,主机停止过程中会自动释放Autofac根容器,因此手动注册上述释放逻辑并非必须。但如果你的业务场景中有额外资源需要和容器同步释放,或者需要确保自定义的释放逻辑执行,保留这段代码是完全可行的。
内容的提问来源于stack exchange,提问作者hng
相关产品推荐
相关产品推荐

