asp.net core - job - Inyección de dependencia Hangfire con núcleo.net
hangfire recurring job (4)
¿Cómo puedo usar la inyección de dependencia predeterminada de .net core en Hangfire?
Soy nuevo en Hangfire y estoy buscando un ejemplo que funcione con el núcleo de asp.net.
Actualmente, Hangfire está profundamente integrado con Asp.Net Core. Instale Hangfire.AspNetCore para configurar el tablero de instrumentos y la integración de DI automáticamente. Entonces, solo necesita definir sus dependencias usando ASP.NET core como siempre.
Por lo que yo sé, puede usar la inyección de dependencia de .net cores de la misma manera que lo haría para cualquier otro servicio.
Puede utilizar un servicio que contenga los trabajos a ejecutar, que se pueden ejecutar como tal
var jobId = BackgroundJob.Enqueue(x => x.SomeTask(passParamIfYouWish));
Aquí hay un ejemplo de la clase de Servicio de Trabajo
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);
}
}
Y en tus proyectos Startup.cs puedes agregar una dependencia como siempre.
services.AddTransient< IClientService, ClientService>();
No estoy seguro de que esto responda a tu pregunta o no
Tuve que iniciar HangFire en la función principal. Así lo resolví:
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>();
}
Vea el ejemplo completo en GitHub https://github.com/gonzigonz/HangfireCore-Example .
Sitio en vivo en http://hangfirecore.azurewebsites.net/
Asegúrate de tener la versión Core de Hangfire:
dotnet add package Hangfire.AspNetCore
Configure su IoC definiendo un
JobActivator
. A continuación se muestra la configuración para usar con el servicio de contenedor central de asp.net predeterminado: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); } }
A continuación, registre hangfire como un servicio en el método
Startup.ConfigureServices
:services.AddHangfire(opt => opt.UseSqlServerStorage("Your Hangfire Connection string"));
Configure hangfire en el método
Startup.Configure
. En relación con su pregunta, la clave es configurar hangfire para usar el nuevoHangfireActivator
que acabamos de definir. Para hacerlo, deberá proporcionar hangfire conIServiceProvider
y esto se puede lograr simplemente agregándolo a la lista de parámetros para el métodoConfigure
. En el tiempo de ejecución, DI proporcionará este servicio para usted: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(); }
Cuando pone en cola un trabajo, use el tipo registrado que normalmente es su interfaz. No uses un tipo concreto a menos que lo hayas registrado de esa manera. Debe utilizar el tipo registrado con su IoC para que Hangfire no lo encuentre. Por ejemplo, digamos que ha registrado los siguientes servicios:
services.AddScoped<DbManager>(); services.AddScoped<IMyService, MyService>();
Entonces podrías poner en cola DbManager
con una versión instanciada de la clase:
BackgroundJob.Enqueue(() => dbManager.DoSomething());
Sin embargo no podrías hacer lo mismo con MyService
. La puesta en cola con una versión instanciada fallaría porque DI fallaría, ya que solo se registra la interfaz. En este caso usted podría poner en cola así:
BackgroundJob.Enqueue<IMyService>( ms => ms.DoSomething());