web-dev-qa-db-ja.com

.netコアを使用したHangfire依存性注入

Hangfireで.netコアのデフォルトの依存性注入を使用するにはどうすればよいですか?

私はHangfireが初めてで、asp.netコアで機能する例を探しています。

48
eadam

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メソッドでハングファイアを設定します。あなたの質問に関連して、keyは、先ほど定義した新しいHangfireActivatorを使用するようにhangfireを構成します。これを行うには、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に登録されているタイプを使用する必要があります。そうしないと、Hangfireはそれを見つけられません。 では、次のサービスを登録したとします:

    services.AddScoped<DbManager>();
    services.AddScoped<IMyService, MyService>();
    

次に、インスタンス化されたバージョンのクラスでDbManagerをキューに入れることができます。

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

ただし、MyServiceでは同じことができませんでした。インターフェイスのみが登録されているため、DIは失敗するため、インスタンス化されたバージョンでのエンキューは失敗します。この場合、次のようにエンキューします。

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

私の知る限り、他のサービスと同じように.netコアの依存性注入を使用できます。

実行されるジョブを含むサービスを使用できます。

var jobId = BackgroundJob.Enqueue(x => x.SomeTask(passParamIfYouWish));

ジョブサービスクラスの例を次に示します

_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>();

これがあなたの質問に答えるかどうかわからない

12
DoritoBandito

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

5
Daniel Genezini

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")));
0
Alexei

現在、HangfireはAsp.Net Coreと緊密に統合されています。 Hangfire.AspNetCoreダッシュボードのセットアップ にインストールし、DI統合を自動的に行います。その後、ASP.NETコアを使用して、常に依存関係を定義する必要があります。

0
Ehsan Mirsaeedi