ASP.NET Core中使用Hangfire时单例服务被多次构造的问题
解决Hangfire使用ASP.NET Core单例服务的问题
我完全懂你遇到的这个坑——明明把XXXService注册成了单例,正常请求里都只会创建一次,但Hangfire一执行AnalyzeRequest就搞出个新实例。这是因为Hangfire默认会自己用Activator.CreateInstance实例化目标类,直接绕开了ASP.NET Core的DI容器。下面给你两种靠谱的解决办法:
方法一:用泛型Enqueue指定服务接口(推荐)
最简单的方式是修改QueueRequest里的调用逻辑,改用泛型版本的BackgroundJob.Enqueue,直接指定你的服务接口:
public void QueueRequest(Guid requestId) { // 让Hangfire从DI容器中解析IXXXService的单例实例 BackgroundJob.Enqueue<IXXXService>(service => service.AnalyzeRequest(requestId)); }
原理很直接:Hangfire识别到你要解析的是接口类型后,会自动用配置好的DI容器去获取实例——而你已经把IXXXService注册成了单例,所以每次都会拿到同一个对象。
方法二:替换Hangfire的作业激活器
如果不想改现有代码结构,你可以替换Hangfire的默认激活器,让它全程用ASP.NET Core的DI容器来创建作业实例:
在Startup.cs的ConfigureServices方法里,配置Hangfire时指定AspNetCoreJobActivator:
services.AddHangfire(config => { config.UseMemoryStorage(); // 配置Hangfire使用ASP.NET Core的服务提供器激活作业类 config.UseActivator(new AspNetCoreJobActivator(services.BuildServiceProvider())); });
这样不管你用this还是其他方式调用Enqueue,Hangfire都会从DI容器里拿XXXService的单例,不会再自己新建实例。
验证效果
改完后你可以盯着控制台看XXXService构造函数里的Console.WriteLine("xxx")——现在不管触发多少次后台作业,只会看到一次这个输出,说明Hangfire确实在用单例实例了。
内容的提问来源于stack exchange,提问作者Maor Veitsman
相关产品推荐
相关产品推荐

