Files
StoreWeb/Core/MAX.Framework/DependencyInjection/HangfireServiceCollectionExtensions.cs
2026-11-03 12:17:49 +08:00

56 lines
2.5 KiB
C#

using Hangfire;
using Hangfire.MySql;
using HangfireBasicAuthenticationFilter;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using MySql.Data.MySqlClient;
namespace MAX.Framework.DependencyInjection;
/// <summary>宿主共享的后台任务存储、执行服务与看板入口。</summary>
public static class HangfireServiceCollectionExtensions
{
/// <summary>从宿主配置注册 Hangfire;任务数据库由独立的 FreeSql 单例管理。</summary>
public static IServiceCollection AddStoreHangfire(this IServiceCollection services, IConfiguration configuration)
{
foreach (var key in new[] { "Hangfire:ConnectionString", "Hangfire:Dashboard:User", "Hangfire:Dashboard:Pass" })
{
if (string.IsNullOrWhiteSpace(configuration[key]))
throw new InvalidOperationException($"缺少宿主配置 {key},无法启动 Hangfire。");
}
var connection = new MySqlConnectionStringBuilder(configuration["Hangfire:ConnectionString"])
{
// Hangfire MySQL 存储的建表和查询语句依赖用户变量。
AllowUserVariables = true
};
services.AddKeyedSingleton<IFreeSql>("HangfireConnection", (_, _) =>
new FreeSql.FreeSqlBuilder().UseConnectionString(FreeSql.DataType.MySql, connection.ConnectionString)
.UseAdoConnectionPool(true).Build());
services.AddHangfire((provider, config) => config
.SetDataCompatibilityLevel(CompatibilityLevel.Version_180)
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseStorage(new MySqlStorage(provider.GetRequiredKeyedService<IFreeSql>("HangfireConnection"),
new MySqlStorageOptions { TablesPrefix = "Hangfire_" })));
services.AddHangfireServer();
services.AddSingleton(new DashboardOptions
{
Authorization = new[]
{
new HangfireCustomBasicAuthenticationFilter
{
User = configuration["Hangfire:Dashboard:User"],
Pass = configuration["Hangfire:Dashboard:Pass"]
}
}
});
return services;
}
/// <summary>在宿主认证、授权中间件之后挂载共享看板。</summary>
public static IApplicationBuilder UseStoreHangfire(this IApplicationBuilder app)
=> app.UseHangfireDashboard("/hangfire", app.ApplicationServices.GetRequiredService<DashboardOptions>());
}