编辑
2025-09-24
C#
00

目录

代码
Program.cs
IConfigurationExtensions.cs
appsettings.json
appsettings.Development.json
运行
扩展方法的关键特性
使用场景
结论

IConfiguration 是 .NET Core 中用于访问应用程序配置的关键接口。通过扩展方法,我们可以更方便地操作配置对象,简化读取和验证配置的过程。以下是对 IConfigurationExtensions 类的详细介绍和重写示例。

代码

nuget 安装

PowerShell
Microsoft.Extensions.Configuration.Abstractions Microsoft.Extensions.Configuration.Binder Microsoft.Extensions.Configuration Microsoft.Extensions.Configuration.FileExtensions Microsoft.Extensions.Configuration.Json Microsoft.Extensions.Configuration.EnvironmentVa

image.png

Program.cs

C#
using Microsoft.Extensions.Configuration; using System; using System.Collections.Generic; using System.IO; using System.Linq; namespace ConfigurationExtensionsDemo { class Program { static void Main(string[] args) { Console.WriteLine("增强版 IConfiguration 扩展方法演示"); Console.WriteLine("================================"); // 创建配置构建器 IConfiguration configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true) .AddEnvironmentVariables() .Build(); // 示例1: 检查配置节点是否存在 Console.WriteLine("\n1. 检查配置节点是否存在:"); Console.WriteLine($"AppSettings节点存在: {configuration.Exists("AppSettings")}"); Console.WriteLine($"NonExistentNode节点存在: {configuration.Exists("NonExistentNode")}"); // 示例2: 获取基本类型配置值 Console.WriteLine("\n2. 获取基本类型值:"); string appName = configuration.GetValue<string>("AppSettings:AppName"); Console.WriteLine($"应用名称: {appName}"); // 示例3: 使用扩展方法获取复杂类型 Console.WriteLine("\n3. 使用扩展方法获取复杂类型:"); var appSettings = configuration.Get<AppSettings>("AppSettings"); Console.WriteLine($"应用名称: {appSettings.AppName}"); Console.WriteLine($"版本: {appSettings.Version}"); Console.WriteLine($"是否为开发环境: {appSettings.IsDevelopment}"); // 示例4: 使用GetValueOrDefault获取值或默认值 Console.WriteLine("\n4. 使用GetValueOrDefault获取值或默认值:"); int maxConnections = configuration.GetValueOrDefault<int>("Database:MaxConnections", 100); Console.WriteLine($"最大连接数: {maxConnections}"); // 示例5: 使用GetSafe安全获取值 Console.WriteLine("\n5. 使用GetSafe安全获取值:"); bool enableCache = configuration.GetSafe<bool>("Cache:Enabled", false); Console.WriteLine($"启用缓存: {enableCache}"); // 示例6: 使用GetForEnvironment获取环境特定配置 Console.WriteLine("\n6. 使用GetForEnvironment获取环境特定配置:"); string logLevel = configuration.GetForEnvironment<string>("Logging:LogLevel", "Development"); Console.WriteLine($"开发环境日志级别: {logLevel}"); // 示例7: 使用GetDictionary获取配置字典 Console.WriteLine("\n7. 使用GetDictionary获取配置字典:"); var featureFlags = configuration.GetDictionary("FeatureFlags"); Console.WriteLine("功能标志:"); foreach (var flag in featureFlags) { Console.WriteLine($" {flag.Key}: {flag.Value}"); } // 示例8: 使用TryGet尝试获取配置 Console.WriteLine("\n8. 使用TryGet尝试获取配置:"); if (configuration.TryGet<string>("AppSettings:Theme", out var theme)) { Console.WriteLine($"主题: {theme}"); } else { Console.WriteLine("主题配置不存在或无法解析"); } // 示例9: 使用Validate验证配置 Console.WriteLine("\n9. 使用Validate验证配置:"); bool isValidPort = configuration.Validate<int>("Database:Port", port => port > 0 && port < 65536); Console.WriteLine($"数据库端口配置有效: {isValidPort}"); // 示例10: 使用GetList获取配置列表 Console.WriteLine("\n10. 使用GetList获取配置列表:"); var allowedOrigins = configuration.GetList<string>("Cors:AllowedOrigins"); Console.WriteLine("允许的跨域来源:"); foreach (var origin in allowedOrigins) { Console.WriteLine($" {origin}"); } // 示例11: 使用GetMap获取配置映射 Console.WriteLine("\n11. 使用GetMap获取配置映射:"); var userRoles = configuration.GetMap<int, UserRole>("UserRoles"); Console.WriteLine("用户角色映射:"); foreach (var role in userRoles) { Console.WriteLine($" 用户ID {role.Key}: {role.Value.RoleName} (权限等级: {role.Value.PermissionLevel})"); } Console.WriteLine("\n按任意键退出..."); Console.ReadKey(); } } // 配置模型类 public class AppSettings { public string AppName { get; set; } public string Version { get; set; } public bool IsDevelopment { get; set; } public string Theme { get; set; } } public class DatabaseSettings { public string ConnectionString { get; set; } public string Provider { get; set; } public int Port { get; set; } public int MaxConnections { get; set; } } public class LoggingSettings { public string LogLevel { get; set; } public string FilePath { get; set; } } public class UserRole { public string RoleName { get; set; } public int PermissionLevel { get; set; } } }

IConfigurationExtensions.cs

C#
using Microsoft.Extensions.Configuration; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Threading.Tasks; namespace ConfigurationExtensionsDemo { /// <summary> /// IConfiguration接口的增强扩展方法 /// </summary> public static class IConfigurationExtensions { /// <summary> /// 判断配置节点是否存在 /// </summary> /// <param name="configuration">配置对象</param> /// <param name="key">节点路径</param> /// <returns>是否存在</returns> public static bool Exists(this IConfiguration configuration, string key) { return configuration.GetSection(key).Exists(); } /// <summary> /// 获取配置节点并转换成指定类型 /// </summary> /// <typeparam name="T">节点类型</typeparam> /// <param name="configuration">配置对象</param> /// <param name="key">节点路径</param> /// <returns>节点类型实例</returns> public static T Get<T>(this IConfiguration configuration, string key) { return configuration.GetSection(key).Get<T>(); } /// <summary> /// 获取配置节点并转换成指定类型 /// </summary> /// <typeparam name="T">节点类型</typeparam> /// <param name="configuration">配置对象</param> /// <param name="key">节点路径</param> /// <param name="configureOptions">配置值绑定到指定类型额外配置</param> /// <returns>节点类型实例</returns> public static T Get<T>(this IConfiguration configuration , string key , Action<BinderOptions> configureOptions) { return configuration.GetSection(key).Get<T>(configureOptions); } /// <summary> /// 获取节点配置 /// </summary> /// <param name="configuration">配置对象</param> /// <param name="key">节点路径</param> /// <param name="type">节点类型</param> /// <returns><see cref="object"/> 实例</returns> public static object Get(this IConfiguration configuration , string key , Type type) { return configuration.GetSection(key).Get(type); } /// <summary> /// 获取节点配置 /// </summary> /// <param name="configuration">配置对象</param> /// <param name="key">节点路径</param> /// <param name="type">节点类型</param> /// <param name="configureOptions">配置值绑定到指定类型额外配置</param> /// <returns><see cref="object"/> 实例</returns> public static object Get(this IConfiguration configuration , string key , Type type , Action<BinderOptions> configureOptions) { return configuration.GetSection(key).Get(type, configureOptions); } /// <summary> /// 获取配置节点值或默认值 /// </summary> /// <typeparam name="T">值类型</typeparam> /// <param name="configuration">配置对象</param> /// <param name="key">节点路径</param> /// <param name="defaultValue">默认值</param> /// <returns>配置值或默认值</returns> public static T GetValueOrDefault<T>(this IConfiguration configuration, string key, T defaultValue = default) { if (!configuration.Exists(key)) return defaultValue; try { return configuration.GetValue<T>(key); } catch { return defaultValue; } } /// <summary> /// 安全获取配置值,如果转换失败返回默认值 /// </summary> /// <typeparam name="T">值类型</typeparam> /// <param name="configuration">配置对象</param> /// <param name="key">节点路径</param> /// <param name="defaultValue">默认值</param> /// <returns>配置值或默认值</returns> public static T GetSafe<T>(this IConfiguration configuration, string key, T defaultValue = default) { if (!configuration.Exists(key)) return defaultValue; string value = configuration[key]; if (string.IsNullOrEmpty(value)) return defaultValue; try { var converter = TypeDescriptor.GetConverter(typeof(T)); if (converter.CanConvertFrom(typeof(string))) return (T)converter.ConvertFrom(value); return (T)Convert.ChangeType(value, typeof(T)); } catch { return defaultValue; } } /// <summary> /// 根据环境获取配置值 /// </summary> /// <typeparam name="T">值类型</typeparam> /// <param name="configuration">配置对象</param> /// <param name="key">基础键</param> /// <param name="environment">环境名称</param> /// <returns>环境特定的配置值</returns> public static T GetForEnvironment<T>(this IConfiguration configuration, string key, string environment) { string envSpecificKey = $"{key}:{environment}"; // 尝试获取环境特定配置 if (configuration.Exists(envSpecificKey)) { var value = configuration.Get<T>(envSpecificKey); if (value != null) return value; } // 回退到基础配置 return configuration.Get<T>(key); } /// <summary> /// 读取指定键的子配置为字典 /// </summary> /// <param name="configuration">配置对象</param> /// <param name="key">节点路径</param> /// <returns>键值对字典</returns> public static Dictionary<string, string> GetDictionary(this IConfiguration configuration, string key) { var section = configuration.GetSection(key); if (!section.Exists()) return new Dictionary<string, string>(); return section.GetChildren() .ToDictionary( child => child.Key, child => child.Value ); } /// <summary> /// 异步获取配置并转换为指定类型 /// </summary> /// <typeparam name="T">节点类型</typeparam> /// <param name="configuration">配置对象</param> /// <param name="key">节点路径</param> /// <returns>节点类型实例的任务</returns> public static Task<T> GetAsync<T>(this IConfiguration configuration, string key) { return Task.FromResult(configuration.Get<T>(key)); } /// <summary> /// 尝试获取配置并转换为指定类型 /// </summary> /// <typeparam name="T">节点类型</typeparam> /// <param name="configuration">配置对象</param> /// <param name="key">节点路径</param> /// <param name="value">输出值</param> /// <returns>是否成功获取到值</returns> public static bool TryGet<T>(this IConfiguration configuration, string key, out T value) { value = default; if (!configuration.Exists(key)) return false; try { value = configuration.Get<T>(key); return true; } catch { return false; } } /// <summary> /// 检查配置是否满足指定条件 /// </summary> /// <typeparam name="T">值类型</typeparam> /// <param name="configuration">配置对象</param> /// <param name="key">节点路径</param> /// <param name="predicate">条件函数</param> /// <returns>是否满足条件</returns> public static bool Validate<T>(this IConfiguration configuration, string key, Func<T, bool> predicate) { if (!configuration.Exists(key)) return false; try { var value = configuration.Get<T>(key); return predicate(value); } catch { return false; } } /// <summary> /// 获取配置节点的列表 /// </summary> /// <typeparam name="T">项目类型</typeparam> /// <param name="configuration">配置对象</param> /// <param name="key">节点路径</param> /// <returns>列表</returns> public static List<T> GetList<T>(this IConfiguration configuration, string key) { var section = configuration.GetSection(key); if (!section.Exists()) return new List<T>(); var list = new List<T>(); foreach (var child in section.GetChildren()) { try { var item = child.Get<T>(); if (item != null) list.Add(item); } catch { /* 忽略转换错误 */ } } return list; } /// <summary> /// 将配置的所有子节点映射为强类型对象集合 /// </summary> /// <typeparam name="TKey">键类型</typeparam> /// <typeparam name="TValue">值类型</typeparam> /// <param name="configuration">配置对象</param> /// <param name="key">节点路径</param> /// <returns>字典</returns> public static Dictionary<TKey, TValue> GetMap<TKey, TValue>(this IConfiguration configuration, string key) where TKey : IConvertible { var section = configuration.GetSection(key); if (!section.Exists()) return new Dictionary<TKey, TValue>(); var dictionary = new Dictionary<TKey, TValue>(); foreach (var child in section.GetChildren()) { try { var k = (TKey)Convert.ChangeType(child.Key, typeof(TKey)); var v = child.Get<TValue>(); if (v != null) dictionary[k] = v; } catch { /* 忽略转换错误 */ } } return dictionary; } } }

appsettings.json

JSON
{ "AppSettings": { "AppName": "配置扩展示例", "Version": "1.0.0", "IsDevelopment": true, "Theme": "Dark" }, "Database": { "ConnectionString": "Server=localhost;Database=DemoDb;User Id=demo;Password=demo123", "Provider": "SqlServer", "Port": 1433, "MaxConnections": 50 }, "Logging": { "LogLevel": "Information", "FilePath": "logs/app.log", "Development": "Debug" }, "Cache": { "Enabled": true, "ExpirationMinutes": 30 }, "FeatureFlags": { "NewDashboard": "true", "BetaFeatures": "false", "AdvancedSearch": "true" }, "Cors": { "AllowedOrigins": [ "https://example.com", "https://api.example.com", "https://admin.example.com" ] }, "UserRoles": { "1": { "RoleName": "Admin", "PermissionLevel": 100 }, "2": { "RoleName": "Manager", "PermissionLevel": 50 }, "3": { "RoleName": "User", "PermissionLevel": 10 } } }

appsettings.Development.json

JSON
{ "AppSettings": { "IsDevelopment": true }, "Logging": { "LogLevel": "Debug" }, "Database": { "ConnectionString": "Server=localhost;Database=DevDb;User Id=dev;Password=dev123" }, "FeatureFlags": { "BetaFeatures": "true", "ExperimentalApi": "true" } }

运行

image.png

扩展方法的关键特性

  1. 简化访问:通过扩展方法,我们可以直接从 IConfiguration 对象获取配置值,而不需要先调用 GetSection
  2. 类型安全:利用泛型特性 Get<T>() 提供类型安全的配置访问方式,避免类型转换错误。
  3. 灵活性:支持通过 Type 参数动态指定目标类型,适用于运行时类型不确定的场景。
  4. 配置选项:支持通过 BinderOptions 自定义绑定行为,例如允许绑定到非公共属性。

使用场景

这些扩展方法在以下场景特别有用:

  • 读取分层配置(如 JSON 配置文件)
  • 将配置节点映射到强类型对象
  • 检查配置值是否存在,避免空引用异常
  • 需要动态决定目标类型的场合

结论

IConfigurationExtensions 类通过扩展方法增强了 .NET Core 配置系统的易用性。这些方法封装了常见的配置操作,使代码更简洁、更易读,同时保持类型安全性。示例代码展示了如何在实际应用中使用这些扩展方法读取不同类型的配置值,对于构建具有良好配置管理的应用程序非常有帮助。

相关信息

通过网盘分享的文件:AppIConfiguration.zip 链接: https://pan.baidu.com/s/11orXn8qXA0vSgWdYbtU0Pg?pwd=bcra 提取码: bcra --来自百度网盘超级会员v9的分享

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!