如何在Hangfire中使用.net core的默认依赖注入?
我是Hangfire的新手,正在寻找一个与asp.net核心兼容的例子。
请参阅GitHub https://github.com/gonzigonz/HangfireCore-Example上的完整示例。 在http://hangfirecore.azurewebsites.net/的现场
dotnet add package Hangfire.AspNetCore
JobActivator
来配置您的IoC。以下是与默认的asp.net核心容器服务一起使用的配置:
public class HangfireActivator : Hangfire.JobActivator
{
private readonly IServiceProvider _serviceProvider;
public HangfireActivator(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public override object ActivateJob(Type type)
{
return _serviceProvider.GetService(type);
}
}
Startup.ConfigureServices
方法中注册hangfire作为服务:
services.AddHangfire(opt =>
opt.UseSqlServerStorage("Your Hangfire Connection string"));
Startup.Configure
方法中配置hangfire。与您的问题相关,关键是配置hangfire以使用我们刚才定义的新HangfireActivator
。要做到这一点,你必须提供与IServiceProvider
的hangfire,这可以通过将它添加到Configure
方法的参数列表来实现。在运行时,DI将为您提供此服务:
public void Configure(
IApplicationBuilder app,
IHostingEnvironment env,
ILoggerFactory loggerFactory,
IServiceProvider serviceProvider)
{
...
// Configure hangfire to use the new JobActivator we defined.
GlobalConfiguration.Configuration
.UseActivator(new HangfireActivator(serviceProvider));
// The rest of the hangfire config as usual.
app.UseHangfireServer();
app.UseHangfireDashboard();
}
services.AddScoped<DbManager>();
services.AddScoped<IMyService, MyService>();
然后你可以用一个实例化的类来排队DbManager
:
BackgroundJob.Enqueue(() => dbManager.DoSomething());
但是你不能对MyService
做同样的事情。使用实例化版本进行入队将失败,因为DI将失败,因为只有接口已注册。在这种情况下,你会像这样入队:
BackgroundJob.Enqueue<IMyService>( ms => ms.DoSomething());
据我所知,您可以像使用任何其他服务一样使用.net核心依赖注入。
您可以使用包含要执行的作业的服务,这样可以执行
var jobId = BackgroundJob.Enqueue(x => x.SomeTask(passParamIfYouWish));
以下是Job Service类的示例
public class JobService : IJobService
{
private IClientService _clientService;
private INodeServices _nodeServices;
//Constructor
public JobService(IClientService clientService, INodeServices nodeServices)
{
_clientService = clientService;
_nodeServices = nodeServices;
}
//Some task to execute
public async Task SomeTask(Guid subject)
{
// Do some job here
Client client = _clientService.FindUserBySubject(subject);
}
}
在您的项目Startup.cs中,您可以正常添加依赖项
services.AddTransient< IClientService, ClientService>();
不确定这是否回答了你的问题
DoritoBandito的回答不完整或已弃用。
public class EmailSender { public EmailSender(IDbContext dbContext, IEmailService emailService) { _dbContext = dbContext; _emailService = emailService; } }
注册服务:
services.AddTransient<IDbContext, TestDbContext>(); services.AddTransient<IEmailService, EmailService>();
排队:
BackgroundJob.Enqueue<EmailSender>(x => x.Send(13, "Hello!"));
资料来源:http://docs.hangfire.io/en/latest/background-methods/passing-dependencies.html
目前,Hangfire与Asp.Net Core深度集成。自动将Hangfire.AspNetCore安装到set up the dashboard和DI集成。然后,您只需要像往常一样使用ASP.NET核心定义依赖项。
我必须在main函数中启动HangFire。这就是我解决它的方式:
public static void Main(string[] args)
{
var host = CreateWebHostBuilder(args).Build();
using (var serviceScope = host.Services.CreateScope())
{
var services = serviceScope.ServiceProvider;
try
{
var liveDataHelper = services.GetRequiredService<ILiveDataHelper>();
var justInitHangfire = services.GetRequiredService<IBackgroundJobClient>();
//This was causing an exception (HangFire is not initialized)
RecurringJob.AddOrUpdate(() => liveDataHelper.RePopulateAllConfigDataAsync(), Cron.Daily());
// Use the context here
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "Can't start " + nameof(LiveDataHelper));
}
}
host.Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
如果您尝试使用ASP.NET Core(在ASP.NET Core 2.2中测试)快速设置Hangfire,您还可以使用Hangfire.MemoryStorage。所有配置都可以在Startup.cs
中执行:
using Hangfire;
using Hangfire.MemoryStorage;
public void ConfigureServices(IServiceCollection services)
{
services.AddHangfire(opt => opt.UseMemoryStorage());
JobStorage.Current = new MemoryStorage();
}
protected void StartHangFireJobs(IApplicationBuilder app, IServiceProvider serviceProvider)
{
app.UseHangfireServer();
app.UseHangfireDashboard();
//TODO: move cron expressions to appsettings.json
RecurringJob.AddOrUpdate<SomeJobService>(
x => x.DoWork(),
"* * * * *");
RecurringJob.AddOrUpdate<OtherJobService>(
x => x.DoWork(),
"0 */2 * * *");
}
public void Configure(IApplicationBuilder app, IServiceProvider serviceProvider)
{
StartHangFireJobs(app, serviceProvider)
}
当然,一切都存储在内存中,一旦应用程序池被回收,它就会丢失,但它是一种快速的方法,可以看到一切都按照预期以最少的配置工作。
要切换到SQL Server数据库持久性,您应该安装Hangfire.SqlServer
包并简单地配置它而不是内存存储:
services.AddHangfire(opt => opt.UseSqlServerStorage(Configuration.GetConnectionString("Default")));