.NET Core 5 Windows Service集成Autofac依赖注入的实现问题咨询
解决方案
核心原因
通用主机(Windows Service模板使用的就是通用主机)没有ASP.NET Core Web主机自带的Startup类约定扫描逻辑,你把ConfigureContainer放在BackgroundWorker里自然不会被触发。你已经完成了Autofac和微软DI的核心集成配置,只需要补充Autofac容器的自定义注册逻辑即可。
实现方式(两种可选)
方式一:直接在HostBuilder链式配置中注册(推荐,最简洁)
直接调用IHostBuilder的泛型ConfigureContainer<ContainerBuilder>扩展方法,就能完成Autofac原生注册逻辑,包括模块注册、拦截器、属性注入等高级特性的配置。
修改后的CreateHostBuilder代码如下:
public static IHostBuilder CreateHostBuilder(string[] args) { IConfiguration configuration = new ConfigurationBuilder() .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddEnvironmentVariables() .AddCommandLine(args) .Build(); return Host.CreateDefaultBuilder(args) .UseWindowsService(options => { options.ServiceName = "MariaDB Backup Service"; }) // 已经配置的Autofac服务工厂不用改 .UseServiceProviderFactory(new AutofacServiceProviderFactory()) // 新增Autofac原生配置逻辑 .ConfigureContainer<ContainerBuilder>(builder => { // 这里写你原来要放在ConfigureContainer里的所有逻辑 builder.RegisterModule<ExampleRestApiModule>(); // 其他Autofac原生注册逻辑都可以在这里写 }) .ConfigureServices((hostContext, services) => { // 原来的微软DI注册逻辑不用改 var backupServiceConfig = new List<BackupServiceConfig>(); configuration.Bind("Tasks:BackupService", backupServiceConfig); services.AddSingleton(backupServiceConfig); services.AddTransient<IBackupCommandFactory, BackupCommandFactory>(); services.AddTransient<MariaDbBackupService>(); services.AddHostedService<BackgroundWorker>(); }); }
这种方式下,Autofac和微软DI的注册会自动合并,你在BackgroundWorker的构造函数中注入的服务,不管是通过ConfigureServices注册的,还是通过Autofac注册的,都可以正常解析。
方式二:沿用Startup类的配置风格(适合需要分离配置的场景)
如果你习惯了Web项目的Startup分离写法,可以自己定义Startup类,手动绑定配置逻辑:
- 先定义Startup类:
public class Startup { public IConfiguration Configuration { get; } public Startup(IConfiguration configuration) { Configuration = configuration; } public void ConfigureServices(IServiceCollection services) { // 把原来ConfigureServices里的逻辑移到这里 var backupServiceConfig = new List<BackupServiceConfig>(); Configuration.Bind("Tasks:BackupService", backupServiceConfig); services.AddSingleton(backupServiceConfig); services.AddTransient<IBackupCommandFactory, BackupCommandFactory>(); services.AddTransient<MariaDbBackupService>(); services.AddHostedService<BackgroundWorker>(); } public void ConfigureContainer(ContainerBuilder builder) { builder.RegisterModule<ExampleRestApiModule>(); } }
- 修改CreateHostBuilder逻辑:
public static IHostBuilder CreateHostBuilder(string[] args) { IConfiguration configuration = new ConfigurationBuilder() .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddEnvironmentVariables() .AddCommandLine(args) .Build(); var startup = new Startup(configuration); return Host.CreateDefaultBuilder(args) .UseWindowsService(options => { options.ServiceName = "MariaDB Backup Service"; }) .UseServiceProviderFactory(new AutofacServiceProviderFactory()) .ConfigureServices(services => startup.ConfigureServices(services)) .ConfigureContainer<ContainerBuilder>(builder => startup.ConfigureContainer(builder)); }
两种方式都可以实现和ASP.NET Core Web项目完全一致的Autofac集成效果,所有Autofac高级特性都可以正常使用。
内容的提问来源于stack exchange,提问作者Stephen York
相关产品推荐
相关产品推荐

