我正在尝试将嵌入在 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>();
非常奇怪的是,传递给 JobProcessingModule.Load(containerBuilder)
的 containerBuilder 实例与调用 RegisterModule
的 containerBuilder 对象不同。
但是,使用简化的可注入项的实验表明这是正常的,并且注入的项在返回的容器的注册中仍然可见。
重新检查记录的失败,我们注意到该类是由类名而不是由接口提及的。通过删除接口注册来改变注册,像这样
builder.RegisterType<ProcessManager>();//.As<IProcessManager>();
导致在 Hangfire 控制台主机中找到 ProcessManager,但在创建作业时导致 Web 应用程序中的运行时错误。
以两种方式注册它导致ProcessManager被两者找到,新问题浮出水面:无法解决依赖关系。然而,这只是同一问题的一个新案例。
虽然这让我可以继续让控制台主机工作,但我不喜欢我不理解的代码。 为什么控制台主机需要通过类名注册,而 Web 应用不需要?
导致这种情况的原因也导致 Hangfire.IBackgroundJobClient 无法解析到后台作业客户端。这是一个hangfire类,所以看起来确实存在一个根本问题。
答案 0 :(得分:0)
经过长时间的调查,最终通过实验证实了这段代码
_recurringJobManager.AddOrUpdate(
insertResult.ToString(),
pm => pm.RunScheduledJobs(insertResult), interval.CrontabExpression
);
对问题中描述的行为负责。 AddOrUpdate
是通用方法。当它没有显式类型化时,它从传递给它的对象的类中获取它的类型。当方法显式类型为接口时,像这样
_recurringJobManager.AddOrUpdate<IProcessManager>(
insertResult.ToString(),
pm => pm.RunScheduledJobs(insertResult), interval.CrontabExpression
);
它仍然与对象兼容,但 Hangfire 获取的类型是接口,控制台应用程序可以从其接口解析 ProcessManager
。
为什么在 Web 托管的 Hangfire 服务器中没有出现问题仍然是一个谜,但至少现在我对在我没有的情况下没有问题感到困惑。