feat(archival): 🚧 add MediatR/Hangfire integration

This commit is contained in:
Collin M. Barrett 2020-09-13 20:10:45 -05:00
parent 4fab66a396
commit f291881cef
6 changed files with 141 additions and 2 deletions

View file

@ -0,0 +1,39 @@
using System.Threading;
using System.Threading.Tasks;
using FilterLists.SharedKernel.Apis.Clients;
using MediatR;
namespace FilterLists.Archival.Application.Commands
{
public static class ArchiveList
{
public class Command : IRequest
{
public Command(int listId)
{
ListId = listId;
}
public int ListId { get; }
}
public class Handler : IRequestHandler<Command, Unit>
{
private readonly IDirectoryApi _directory;
public Handler(IDirectoryApi directory)
{
_directory = directory;
}
public async Task<Unit> Handle(Command request, CancellationToken cancellationToken)
{
var listDetails = await _directory.GetListDetailsAsync(5, cancellationToken);
// TODO: archive
return Unit.Value;
}
}
}
}

View file

@ -0,0 +1,38 @@
using System.Threading;
using System.Threading.Tasks;
using FilterLists.Archival.Infrastructure.Scheduling;
using FilterLists.SharedKernel.Apis.Clients;
using MediatR;
namespace FilterLists.Archival.Application.Commands
{
public static class EnqueueArchiveAllLists
{
public class Command : IRequest
{
}
public class Handler : IRequestHandler<Command, Unit>
{
private readonly IDirectoryApi _directory;
private readonly IMediator _mediator;
public Handler(IDirectoryApi directory, IMediator mediator)
{
_directory = directory;
_mediator = mediator;
}
public async Task<Unit> Handle(Command request, CancellationToken cancellationToken)
{
var lists = await _directory.GetListsAsync(cancellationToken);
foreach (var list in lists)
{
_mediator.Enqueue(new ArchiveList.Command(list.Id));
}
return Unit.Value;
}
}
}
}

View file

@ -17,7 +17,6 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="8.1.0" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

View file

@ -20,6 +20,7 @@
<PackageReference Include="Hangfire.AspNetCore" Version="1.7.12" />
<PackageReference Include="HangFire.Redis.StackExchange" Version="1.8.4" />
<PackageReference Include="LibGit2Sharp" Version="0.26.2" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="8.1.0" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

View file

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

View file

@ -0,0 +1,57 @@
using System;
using Hangfire;
using MediatR;
using Newtonsoft.Json;
namespace FilterLists.Archival.Infrastructure.Scheduling
{
/// <remarks>https://codeopinion.com/background-commands-mediatr-hangfire/</remarks>
internal static class HangfireExtension
{
public static IGlobalConfiguration UseMediatR(this IGlobalConfiguration config, IMediator mediator)
{
config.UseActivator(new MediatRJobActivator(mediator));
GlobalConfiguration.Configuration.UseSerializerSettings(
new JsonSerializerSettings {TypeNameHandling = TypeNameHandling.Objects});
return config;
}
}
internal class MediatRJobActivator : JobActivator
{
private readonly IMediator _mediator;
public MediatRJobActivator(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 SendCommand(IRequest request)
{
_mediator.Send(request);
}
}
public static class MediatRExtension
{
public static void Enqueue(this IMediator mediator, IRequest request)
{
BackgroundJob.Enqueue<HangfireMediator>(m => m.SendCommand(request));
}
}
}