Hangfireで.netコアのデフォルトの依存性注入を使用するにはどうすればよいですか?
私はHangfireが初めてで、asp.netコアで機能する例を探しています。
GitHubの完全な例を参照してください https://github.com/gonzigonz/HangfireCore-Example 。
ライブサイト http://hangfirecore.azurewebsites.net/
Hangfireのコアバージョンがあることを確認します。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
メソッドでハングファイアを設定します。あなたの質問に関連して、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();
}
ジョブをエンキューするときは、通常はインターフェイスである登録済みのタイプを使用します。そのように登録しない限り、具象型を使用しないでください。 IoCに登録されているタイプを使用する必要があります。そうしないと、Hangfireはそれを見つけられません。 例では、次のサービスを登録したとします:
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));
ジョブサービスクラスの例を次に示します
_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
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")));
現在、HangfireはAsp.Net Coreと緊密に統合されています。 Hangfire.AspNetCore を ダッシュボードのセットアップ にインストールし、DI統合を自動的に行います。その後、ASP.NETコアを使用して、常に依存関係を定義する必要があります。