using Hangfire; using MAX.Framework.DependencyInjection; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; /// 不连接数据库,检查宿主配置边界及共享服务注册。 internal static class HangfireChecks { public static void Run() { var settings = new Dictionary { ["Hangfire:ConnectionString"] = "Server=localhost;Database=hangfire;Uid=test;Pwd=test", ["Hangfire:Dashboard:User"] = "test", ["Hangfire:Dashboard:Pass"] = "test" }; foreach (var key in settings.Keys) { foreach (var missing in new string?[] { null, " " }) { var invalid = new Dictionary(settings) { [key] = missing }; var services = new ServiceCollection(); try { services.AddStoreHangfire(new ConfigurationBuilder().AddInMemoryCollection(invalid).Build()); throw new Exception("Expected missing configuration failure: " + key); } catch (InvalidOperationException ex) when (ex.Message.Contains(key)) { } if (services.Count != 0) throw new Exception("Invalid configuration partially registered services"); } } var valid = new ServiceCollection(); valid.AddStoreHangfire(new ConfigurationBuilder().AddInMemoryCollection(settings).Build()); if (valid.Count(d => d.ServiceType == typeof(IFreeSql) && Equals(d.ServiceKey, "HangfireConnection")) != 1 || valid.Count(d => d.ServiceType == typeof(JobStorage)) != 1 || valid.Count(d => d.ServiceType == typeof(IHostedService)) != 1 || valid.Count(d => d.ServiceType == typeof(DashboardOptions)) != 1) throw new Exception("Expected one shared storage, worker and dashboard registration"); using var provider = valid.BuildServiceProvider(); var database = provider.GetRequiredKeyedService("HangfireConnection"); if (!ReferenceEquals(database, provider.GetRequiredKeyedService("HangfireConnection"))) throw new Exception("Task database must be a singleton"); if (provider.GetRequiredService().Authorization.Count() != 1) throw new Exception("Dashboard authentication missing"); Console.WriteLine("PASS Hangfire configuration and shared registrations (no database connection)"); } }