fix(archival): 🐛 use default AspNetJobActivator so service lifetimes are respected

This commit is contained in:
Collin M. Barrett 2020-09-26 13:14:48 -05:00
parent ff186edb16
commit 6312164aa9
2 changed files with 6 additions and 47 deletions

View file

@ -1,6 +1,5 @@
using System;
using Hangfire;
using MediatR;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
@ -15,11 +14,7 @@ internal static class ConfigurationExtensions
public static void AddSchedulingServices(this IServiceCollection services, IConfiguration configuration)
{
_redis = ConnectionMultiplexer.Connect(configuration.GetConnectionString("SchedulingConnection"));
services.AddHangfire((provider, globalConfiguration) =>
{
var mediator = provider.GetService<IMediator>();
globalConfiguration.UseRedisStorage(_redis).UseMediatR(mediator);
});
services.AddHangfire((_, globalConfiguration) => globalConfiguration.UseRedisStorage(_redis).UseMediatR());
}
public static void UseScheduling(this IApplicationBuilder app)

View file

@ -6,65 +6,29 @@
namespace FilterLists.Archival.Infrastructure.Scheduling
{
/// <remarks>https://codeopinion.com/background-commands-mediatr-hangfire/</remarks>
public static class RequestExtensions
{
public static void EnqueueBackgroundJob(this IRequest request)
{
// Hangfire replaces CancellationToken at runtime with its own. We just need any in the signature.
// https://docs.hangfire.io/en/latest/background-methods/using-cancellation-tokens.html#cancellationtoken
BackgroundJob.Enqueue<HangfireMediator>(m => m.Send(request, CancellationToken.None));
BackgroundJob.Enqueue<IMediator>(m => m.Send(request, CancellationToken.None));
}
public static void ScheduleBackgroundJob(this IRequest request, TimeSpan delay)
{
BackgroundJob.Schedule<HangfireMediator>(m => m.Send(request, CancellationToken.None), delay);
}
public static void AddOrUpdateRecurringJob(this IRequest request, Func<string> cronExpression)
{
RecurringJob.AddOrUpdate<HangfireMediator>(m => m.Send(request, CancellationToken.None), cronExpression);
BackgroundJob.Schedule<IMediator>(m => m.Send(request, CancellationToken.None), delay);
}
}
internal static class HangfireExtension
{
public static IGlobalConfiguration UseMediatR(this IGlobalConfiguration config, IMediator mediator)
public static IGlobalConfiguration UseMediatR(this IGlobalConfiguration globalConfiguration)
{
config.UseActivator(new MediatorJobActivator(mediator));
/// https://codeopinion.com/background-commands-mediatr-hangfire/
GlobalConfiguration.Configuration.UseSerializerSettings(
new JsonSerializerSettings {TypeNameHandling = TypeNameHandling.Objects});
return config;
}
}
internal class MediatorJobActivator : JobActivator
{
private readonly IMediator _mediator;
public MediatorJobActivator(IMediator mediator)
{
_mediator = mediator;
}
public override object ActivateJob(Type type)
{
return new HangfireMediator(_mediator);
}
}
internal class HangfireMediator
{
private readonly IMediator _mediator;
public HangfireMediator(IMediator mediator)
{
_mediator = mediator;
}
public void Send(IRequest request, CancellationToken cancellationToken)
{
_mediator.Send(request, cancellationToken);
return globalConfiguration;
}
}
}