使用.net核心进行Hangfire依赖注入

问题描述 投票:42回答:6

如何在Hangfire中使用.net core的默认依赖注入?

我是Hangfire的新手,正在寻找一个与asp.net核心兼容的例子。

asp.net-core hangfire
6个回答
48
投票

请参阅GitHub https://github.com/gonzigonz/HangfireCore-Example上的完整示例。 在http://hangfirecore.azurewebsites.net/的现场

  1. 确保您拥有Hangfire的核心版本: dotnet add package Hangfire.AspNetCore
  2. 通过定义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); } }
  3. 接下来在Startup.ConfigureServices方法中注册hangfire作为服务: services.AddHangfire(opt => opt.UseSqlServerStorage("Your Hangfire Connection string"));
  4. 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(); }
  5. 将作业排入队列时,请使用通常是您的界面的注册类型。除非您以这种方式注册,否则请勿使用具体类型。您必须使用在IoC注册的类型,否则Hang​​fire将无法找到它。例如,您已经注册了以下服务: services.AddScoped<DbManager>(); services.AddScoped<IMyService, MyService>();

然后你可以用一个实例化的类来排队DbManager

    BackgroundJob.Enqueue(() => dbManager.DoSomething());

但是你不能对MyService做同样的事情。使用实例化版本进行入队将失败,因为DI将失败,因为只有接口已注册。在这种情况下,你会像这样入队:

    BackgroundJob.Enqueue<IMyService>( ms => ms.DoSomething());

12
投票

据我所知,您可以像使用任何其他服务一样使用.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>();

不确定这是否回答了你的问题


5
投票

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


0
投票

目前,Hangfire与Asp.Net Core深度集成。自动将Hangfire.AspNetCore安装到set up the dashboard和DI集成。然后,您只需要像往常一样使用ASP.NET核心定义依赖项。


0
投票

我必须在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>();
}

0
投票

如果您尝试使用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")));
© www.soinside.com 2019 - 2024. All rights reserved.