我正在尝试将嵌入在 Kestrel 网络服务器中的工作 Hangfire 设置移植到控制台应用程序。我已经修改了网络应用程序,所以它仍然提供了 Hangfire 仪表板,但没有启动自己的 Hangfire 服务器。
我必须移植的代码使用 Autofac。我已将 Hangfire.Autofac 包添加到控制台应用程序中,并且已经执行了Hangfire Autofac .net core 3.1答案中详述的所有步骤
当我创建作业(使用 Web 应用程序)时,控制台应用程序 Hangfire 服务器尝试执行该作业,但我收到以下失败消息:
The requested service 'AED.ServicesLayer.JobProcessing.ProcessManager' has not been registered.
为此,我们检查了控制台应用程序中 Autofac 的设置。这就是我设置容器的方式。
IConfiguration config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.Build();
var containerBuilder = new Autofac.ContainerBuilder();
containerBuilder.RegisterInstance(Log.Logger).AsImplementedInterfaces();
containerBuilder.RegisterModule(new RepositoryModule(config));
containerBuilder.RegisterType<UserService>().As<IUserService>();
containerBuilder.RegisterInstance(config).As<IConfiguration>();
containerBuilder.RegisterModule(new JobProcessingModule(config));
var container = containerBuilder.Build();
当应用程序执行时,遇到断点JobProcessingModule
证明以下代码行已执行。
builder.RegisterType<ProcessManager>().As<IProcessManager>();
很奇怪,传递给的 containerBuilder 实例与JobProcessingModule.Load(containerBuilder)
调用的containerBuilder 对象不同。RegisterModule
然而,简化注射剂的实验表明这是正常的,并且注射的物品在返回的容器的注册中仍然可见。
重新检查记录的失败,我们注意到该类是由类名而不是接口提及的。通过删除接口注册来更改注册,像这样
builder.RegisterType<ProcessManager>();//.As<IProcessManager>();
导致在 Hangfire 控制台主机中找到 ProcessManager,但在创建作业时导致 Web 应用程序中的运行时错误。
两种方式都注册它会导致双方都找到 ProcessManager,并出现一个新问题:无法解决依赖关系。然而,这只是同一问题的一个新案例。
虽然这让我可以继续让控制台主机正常工作,但我不喜欢我不理解的代码。当 Web 应用程序不需要时,为什么控制台主机需要按类名注册?
无论是什么原因,这也导致 Hangfire.IBackgroundJobClient 无法解析到后台作业客户端。这是一个hangfire类,所以看起来确实存在一个基本问题。