
public class GlobalService
{
private static IServiceScope? _currentScope;
private static readonly Lazy<string> _serverAddress = new Lazy<string>(GetServerAddress, true);
private static readonly Lazy<string> _serverPort = new Lazy<string>(GetServerPort, true);
private static DateTime? _serviceStartTime;
// 核心服务
public static ILogger? Logger { get; private set; }
public static IWebHostEnvironment? WebHostEnvironment { get; private set; }
public static IServiceProvider? ServiceProvider { get; private set; }
public static IConfiguration? Configuration { get; private set; }
public static IHttpContextAccessor? HttpContextAccessor { get; private set; }
public static IHostApplicationLifetime? ApplicationLifetime { get; private set; }
// 使用Lazy<T>实现线程安全的延迟初始化
private static readonly Lazy<IServiceScope> _lazyScope = new Lazy<IServiceScope>(
() => ServiceProvider!.CreateScope(),
LazyThreadSafetyMode.ExecutionAndPublication
);
#region 便捷访问属性 - 环境与应用信息
/// <summary>当前应用程序名称</summary>
public static string ApplicationName => WebHostEnvironment?.ApplicationName ?? "UnknownApp";
/// <summary>当前环境名称(Development/Production等)</summary>
public static string EnvironmentName => WebHostEnvironment?.EnvironmentName ?? "Unknown";
/// <summary>应用程序根路径</summary>
public static string ContentRootPath => WebHostEnvironment?.ContentRootPath ?? "";
/// <summary>Web静态文件根路径</summary>
public static string WebRootPath => WebHostEnvironment?.WebRootPath ?? "";
/// <summary>服务启动时间</summary>
public static DateTime ServiceStartTime => _serviceStartTime ??= DateTime.Now;
/// <summary>服务已运行时间</summary>
public static TimeSpan ServiceUptime => DateTime.Now - ServiceStartTime;
/// <summary>检查应用是否处于开发环境</summary>
public static bool IsDevelopment => WebHostEnvironment?.IsDevelopment() ?? false;
/// <summary>检查应用是否处于生产环境</summary>
public static bool IsProduction => WebHostEnvironment?.IsProduction() ?? false;
#endregion
#region 便捷访问属性 - 系统信息
/// <summary>获取操作系统信息</summary>
public static string OSInformation => Environment.OSVersion.ToString();
/// <summary>获取.NET运行时版本</summary>
public static string RuntimeVersion => Environment.Version.ToString();
/// <summary>获取应用进程ID</summary>
public static int ProcessId => Process.GetCurrentProcess().Id;
#endregion
#region 便捷访问属性 - 客户端信息
/// <summary>获取当前请求的客户端IPv4地址(支持代理服务器场景)</summary>
public static string ClientIPv4Address
{
get
{
try
{
var context = HttpContextAccessor?.HttpContext;
if (context == null) return "Unknown";
// 优先从请求头获取代理IP(如Nginx/X-Forwarded-For)
var ip = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();
if (string.IsNullOrEmpty(ip))
{
ip = context.Connection.RemoteIpAddress?.ToString();
}
// 提取IPv4地址(处理可能的端口或IPv6格式)
if (ip != null)
{
var parts = ip.Split(',', ':', ']').FirstOrDefault(p => !string.IsNullOrEmpty(p.Trim()));
if (IPAddress.TryParse(parts, out var address) && address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
return address.ToString();
}
}
return "Unknown";
}
catch
{
return "Unknown";
}
}
}
/// <summary>获取当前请求的客户端端口号</summary>
public static int? ClientPort
{
get
{
try
{
return HttpContextAccessor?.HttpContext?.Connection?.RemotePort;
}
catch
{
return null;
}
}
}
/// <summary>获取当前请求的完整URL</summary>
public static string? CurrentRequestUrl
{
get
{
try
{
var context = HttpContextAccessor?.HttpContext;
if (context == null) return null;
return $"{context.Request.Scheme}://{context.Request.Host}{context.Request.Path}{context.Request.QueryString}";
}
catch
{
return null;
}
}
}
/// <summary>获取当前认证用户的ID(如果有)</summary>
public static string? CurrentUserId
{
get
{
try
{
var context = HttpContextAccessor?.HttpContext;
return context?.User?.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier")?.Value;
}
catch
{
return null;
}
}
}
/// <summary>获取当前认证用户的名称(如果有)</summary>
public static string? CurrentUserName
{
get
{
try
{
var context = HttpContextAccessor?.HttpContext;
return context?.User?.Identity?.Name;
}
catch
{
return null;
}
}
}
#endregion
#region 便捷访问属性 - 服务地址信息
/// <summary>获取当前服务侦听的IPv4地址</summary>
public static string ServerAddress => _serverAddress.Value;
/// <summary>获取当前服务侦听的端口号</summary>
public static string ServerPort => _serverPort.Value;
/// <summary>获取服务正在监听的完整地址(包含协议和端口)</summary>
public static string ServiceListeningAddress
{
get
{
try
{
if (ServiceProvider == null) return "Unknown";
var server = ServiceProvider.GetRequiredService<IServer>();
var addressesFeature = server.Features.Get<IServerAddressesFeature>();
if (addressesFeature?.Addresses == null || !addressesFeature.Addresses.Any())
{
return "Unknown";
}
return addressesFeature.Addresses.First();
}
catch
{
return "Unknown";
}
}
}
/// <summary>获取当前服务实例的IPv4地址(不包含端口)</summary>
public static string ServiceIPv4Address
{
get
{
try
{
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
return ip.ToString();
}
}
return "127.0.0.1";
}
catch
{
return "127.0.0.1";
}
}
}
/// <summary>获取当前服务实例的端口号</summary>
public static int ServicePort
{
get
{
try
{
var address = ServiceListeningAddress;
if (string.IsNullOrEmpty(address)) return 0;
if (Uri.TryCreate(address, UriKind.Absolute, out var uri))
{
return uri.Port;
}
else if (address.Contains(":"))
{
var parts = address.Split(':').LastOrDefault();
if (int.TryParse(parts, out var port))
{
return port;
}
}
return 0;
}
catch
{
return 0;
}
}
}
#endregion
#region 便捷访问属性 - 请求信息
/// <summary>获取当前请求路径</summary>
public static string? RequestPath => HttpContextAccessor?.HttpContext?.Request?.Path;
/// <summary>获取当前请求方法(GET/POST等)</summary>
public static string? RequestMethod => HttpContextAccessor?.HttpContext?.Request?.Method;
#endregion
/// <summary>创建临时服务作用域(使用后需手动释放)</summary>
public static IServiceScope CreateScope() => ServiceProvider!.CreateScope();
/// <summary>获取当前活动的作用域(单例模式)</summary>
public static IServiceScope CurrentScope => _lazyScope.Value;
/// <summary>初始化全局服务(在应用启动时调用)</summary>
public static void Initialize(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
// 从服务容器中获取核心服务
WebHostEnvironment = serviceProvider.GetRequiredService<IWebHostEnvironment>();
Configuration = serviceProvider.GetRequiredService<IConfiguration>();
HttpContextAccessor = serviceProvider.GetRequiredService<IHttpContextAccessor>();
ApplicationLifetime = serviceProvider.GetRequiredService<IHostApplicationLifetime>();
// 创建全局日志记录器
Logger = serviceProvider.GetRequiredService<ILoggerFactory>()
.CreateLogger("GlobalService");
}
/// <summary>释放全局资源</summary>
public static void Dispose()
{
if (_lazyScope.IsValueCreated)
{
_lazyScope.Value.Dispose();
}
_currentScope = null;
}
/// <summary>从当前作用域获取服务</summary>
public static T GetService<T>() where T : notnull
=> CurrentScope.ServiceProvider.GetRequiredService<T>();
/// <summary>从临时作用域获取服务(使用后需释放作用域)</summary>
public static T GetScopedService<T>() where T : notnull
=> CreateScope().ServiceProvider.GetRequiredService<T>();
/// <summary>从配置中获取强类型配置对象</summary>
public static T GetConfig<T>(string sectionName) where T : new()
{
var config = new T();
Configuration?.GetSection(sectionName).Bind(config);
return config;
}
/// <summary>从配置中获取值</summary>
public static string? GetConfigValue(string key) => Configuration?[key];
/// <summary>优雅地停止应用程序</summary>
public static void StopApplication() => ApplicationLifetime?.StopApplication();
// Fix for CS1061: Replace the incorrect usage of `ServerFeatures` with the correct way to access `IServerAddressesFeature` from the service provider.
private static string GetServerAddress()
{
try
{
if (ServiceProvider == null) return "Unknown";
var server = ServiceProvider.GetRequiredService<IServer>();
var addresses = server.Features.Get<IServerAddressesFeature>()?.Addresses;
return addresses?
.Select(a => new Uri(a))
.FirstOrDefault(uri =>
uri.Host == "localhost" ||
uri.Host == "127.0.0.1" ||
uri.Host.Contains('.')
)?.Host ?? "Unknown";
}
catch
{
return "Unknown";
}
}
private static string GetServerPort()
{
try
{
if (ServiceProvider == null) return "Unknown";
var server = ServiceProvider.GetRequiredService<IServer>();
var addresses = server.Features.Get<IServerAddressesFeature>()?.Addresses;
return addresses?
.Select(a => new Uri(a))
.FirstOrDefault()?
.Port.ToString() ?? "Unknown";
}
catch
{
return "Unknown";
}
}
#region 便捷访问属性 - 内存使用
/// <summary>获取当前应用的内存使用情况</summary>
public static MemoryInfo GetMemoryInfo()
{
try
{
var process = Process.GetCurrentProcess();
return new MemoryInfo
{
WorkingSet = process.WorkingSet64 / (1024 * 1024), // MB
PrivateMemorySize = process.PrivateMemorySize64 / (1024 * 1024), // MB
VirtualMemorySize = process.VirtualMemorySize64 / (1024 * 1024), // MB
PeakWorkingSet = process.PeakWorkingSet64 / (1024 * 1024), // MB
PeakPrivateMemorySize = process.PrivateMemorySize64 / (1024 * 1024),
PeakVirtualMemorySize = process.PeakVirtualMemorySize64 / (1024 * 1024) // MB
};
}
catch (Exception ex)
{
LogException(ex, nameof(GetMemoryInfo));
return new MemoryInfo();
}
}
// 在GlobalService类中添加以下方法
private static void LogException(Exception ex, string methodName)
{
Logger?.LogError(ex, $"GlobalService方法[{methodName}]发生异常: {ex.Message}");
}
/// <summary>内存使用信息类</summary>
public class MemoryInfo
{
public long WorkingSet { get; set; } // 工作集(MB)
public long PrivateMemorySize { get; set; } // 私有内存(MB)
public long VirtualMemorySize { get; set; } // 虚拟内存(MB)
public long PeakWorkingSet { get; set; } // 峰值工作集(MB)
public long PeakPrivateMemorySize { get; set; } // 峰值私有内存(MB)
public long PeakVirtualMemorySize { get; set; } // 峰值虚拟内存(MB)
}
#endregion
/// <summary>
/// 获取GlobalService中所有可展示的信息
/// </summary>
/// <param name="useChinese">是否使用中文显示,默认使用英文</param>
/// <returns>包含所有信息的字典,键为显示名称,值为对应值</returns>
public static Dictionary<string, object> GetAllDisplayInfo(bool useChinese = false)
{
// 中英文显示名称映射
var displayNames = new Dictionary<string, string>
{
// 环境与应用信息
{ "ApplicationName", useChinese ? "应用程序名称" : "Application Name" },
{ "EnvironmentName", useChinese ? "环境名称" : "Environment Name" },
{ "ContentRootPath", useChinese ? "应用程序根路径" : "Content Root Path" },
{ "WebRootPath", useChinese ? "Web静态文件根路径" : "Web Root Path" },
{ "ServiceStartTime", useChinese ? "服务启动时间" : "Service Start Time" },
{ "ServiceUptime", useChinese ? "服务已运行时间" : "Service Uptime" },
{ "IsDevelopment", useChinese ? "是否开发环境" : "Is Development" },
{ "IsProduction", useChinese ? "是否生产环境" : "Is Production" },
// 客户端信息
{ "ClientIPv4Address", useChinese ? "客户端IPv4地址" : "Client IPv4 Address" },
{ "ClientPort", useChinese ? "客户端端口号" : "Client Port" },
{ "CurrentRequestUrl", useChinese ? "当前请求URL" : "Current Request URL" },
{ "CurrentUserId", useChinese ? "当前用户ID" : "Current User ID" },
{ "CurrentUserName", useChinese ? "当前用户名称" : "Current User Name" },
// 服务地址信息
{ "ServerAddress", useChinese ? "服务侦听地址" : "Server Address" },
{ "ServerPort", useChinese ? "服务侦听端口" : "Server Port" },
{ "ServiceListeningAddress", useChinese ? "服务监听地址" : "Service Listening Address" },
{ "ServiceIPv4Address", useChinese ? "服务实例IP地址" : "Service IPv4 Address" },
{ "ServicePort", useChinese ? "服务实例端口" : "Service Port" },
// 请求信息
{ "RequestPath", useChinese ? "当前请求路径" : "Request Path" },
{ "RequestMethod", useChinese ? "当前请求方法" : "Request Method" },
{ "OSInformation", useChinese ? "操作系统信息" : "OS Information" },
{ "RuntimeVersion", useChinese ? ".NET运行时版本" : "Runtime Version" },
{ "ProcessId", useChinese ? "进程ID" : "Process ID" },
{ "MemoryInfo.WorkingSet", useChinese ? "工作集(MB)" : "Working Set (MB)" },
{ "MemoryInfo.PrivateMemorySize", useChinese ? "私有内存(MB)" : "Private Memory Size (MB)" },
{ "MemoryInfo.VirtualMemorySize", useChinese ? "虚拟内存(MB)" : "Virtual Memory Size (MB)" },
{ "MemoryInfo.PeakWorkingSet", useChinese ? "峰值工作集(MB)" : "Peak Working Set (MB)" },
{ "MemoryInfo.PeakPrivateMemorySize", useChinese ? "峰值私有内存(MB)" : "Peak Private Memory Size (MB)" },
{ "MemoryInfo.PeakVirtualMemorySize", useChinese ? "峰值虚拟内存(MB)" : "Peak Virtual Memory Size (MB)" },
};
// 初始化结果字典
var result = new Dictionary<string, object>();
// 添加环境与应用信息
result.Add("ApplicationName", ApplicationName);
result.Add("EnvironmentName", EnvironmentName);
result.Add("ContentRootPath", ContentRootPath);
result.Add("WebRootPath", WebRootPath);
result.Add("ServiceStartTime", ServiceStartTime);
result.Add("ServiceUptime", ServiceUptime);
result.Add("IsDevelopment", IsDevelopment);
result.Add("IsProduction", IsProduction);
// 添加客户端信息
result.Add("ClientIPv4Address", ClientIPv4Address);
result.Add("ClientPort", ClientPort);
result.Add("CurrentRequestUrl", CurrentRequestUrl);
result.Add("CurrentUserId", CurrentUserId);
result.Add("CurrentUserName", CurrentUserName);
// 添加服务地址信息
result.Add("ServerAddress", ServerAddress);
result.Add("ServerPort", ServerPort);
result.Add("ServiceListeningAddress", ServiceListeningAddress);
result.Add("ServiceIPv4Address", ServiceIPv4Address);
result.Add("ServicePort", ServicePort);
// 添加请求信息
result.Add("RequestPath", RequestPath);
result.Add("RequestMethod", RequestMethod);
result.Add("OSInformation", OSInformation);
result.Add("RuntimeVersion", RuntimeVersion);
result.Add("ProcessId", ProcessId);
// 内存信息添加逻辑
var memoryInfo = GetMemoryInfo();
result.Add("MemoryInfo.WorkingSet", memoryInfo.WorkingSet);
result.Add("MemoryInfo.PrivateMemorySize", memoryInfo.PrivateMemorySize);
result.Add("MemoryInfo.VirtualMemorySize", memoryInfo.VirtualMemorySize);
result.Add("MemoryInfo.PeakWorkingSet", memoryInfo.PeakWorkingSet);
result.Add("MemoryInfo.PeakPrivateMemorySize", memoryInfo.PeakPrivateMemorySize);
result.Add("MemoryInfo.PeakVirtualMemorySize", memoryInfo.PeakVirtualMemorySize);
// 转换为显示名称并返回
return result.ToDictionary(
kvp => displayNames[kvp.Key],
kvp => kvp.Value
);
}
}
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddHttpContextAccessor();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
//初始化服务
GlobalService.Initialize(app.Services);
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
[HttpGet]
public IActionResult GetAllDisplayInfoApi()
{
var serverAddress = GlobalService.GetAllDisplayInfo(true);
return Ok(serverAddress);
}