GlobalService类


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);
}