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; /// 宿主共享的后台任务存储、执行服务与看板入口。 public static class HangfireServiceCollectionExtensions { /// 从宿主配置注册 Hangfire;任务数据库由独立的 FreeSql 单例管理。 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("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("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; } /// 在宿主认证、授权中间件之后挂载共享看板。 public static IApplicationBuilder UseStoreHangfire(this IApplicationBuilder app) => app.UseHangfireDashboard("/hangfire", app.ApplicationServices.GetRequiredService()); }