最近在写NET CORE的项目,在非controller和service里面需要用到appsetting.json文件里面的一些配置,查资料大概有几种思路:
- 注入,然后config.GetSection("xxx")获取section。
- 写一个文件监听fileWatch,去监听appsetting.json的变化,读取key-value。
- 使用工具类再创建一遍ConfigurationBuilder: new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile($"appsettings.json", optional: true, reloadOnChange: true)
- 使用IOptions,创建对应的实体类,然后获取实体类。
查资料的时候发现了一个IOptionsMonitor,这个可以监听到文件的变化,结合IOptionsMonitor,我写了一个工具类,具体使用办法如下:
(1)创建appsetting.json对应的实体类文件,属性的名字要与配置文件里面的一一对应。
// 实体类public class AllSetting{ / / 数据库配置 / public ConnectionSetting ConnectionStrings { get; set; } / / 日志模块 / public LoggingSetting Logging { get; set; } / / AllowedHosts / public string AllowedHosts { get; set; }}// 对应的配置文件{ "ConnectionStrings": { "DefaultConnection": "xxxx" //"PgSqlConnection": "xxxx", //"MySqlConnection": "xxxx", //"OracleConnection": "xxxx" }, "Logging": { "LogLevel": { "Default": "Warning" } }, "AllowedHosts": "*", "Gateway": { "Uri": "xxxx" }}
(2)编写工具类AppsettingsUtility。
/// /// 全局获取app的设置工具类 /// public class AppsettingsUtility { /// /// log4net /// private readonly ILog log; /// /// serviceProvider /// private static ServiceProvider serviceProvider; /// /// _services /// private static IServiceCollection _services; /// /// _configuration /// private static IConfiguration _configuration; /// /// 初始化工具类 /// /// public AppsettingsUtility(IServiceCollection services, IConfiguration configuration) { _services = services; _configuration = configuration; // 仓库名 统一的 log = LogManager.GetLogger("仓库名", typeof(AppsettingsUtility)); if (_services == null || _configuration == null) { log.Error("初始化配置工具类发生异常:_services或_configuration为空"); throw new NullReferenceException("初始化配置工具类发生异常"); } try { serviceProvider = _services.BuildServiceProvider(); } catch (Exception ex) { log.Error("_services.BuildServiceProvider()失败:" + ex.ToString()); } } /// /// 获取IOptionsMonitor /// /// 泛型 /// IOptionsMonitor public static IOptionsMonitor GetMonitor() { if (serviceProvider == null) { throw new NullReferenceException("获取失败,ServiceProvider为空"); } if (typeof(T) != typeof(AllSetting)) { // TODO: 要限定传递的参数值或者每个setting都注册一遍 } return serviceProvider.GetRequiredService>(); } /// /// 获取单个的设置实体 /// /// 泛型 /// T public static T GetSettingsModel() { if (serviceProvider == null) { throw new NullReferenceException("获取失败,ServiceProvider为空"); } if (typeof(T) != typeof(AllSetting)) { // TODO: 要限定传递的参数值或者每个setting都注册一遍 } return serviceProvider.GetRequiredService>().CurrentValue; } /// /// 通过key获取设置 /// /// key /// 设置内容 public static string GetSetting(string key) { if (_configuration == null) { throw new NullReferenceException("获取失败,IConfiguration为空"); } if (string.IsNullOrEmpty(key)) { throw new NullReferenceException("获取失败,key不能为空"); } return _configuration.GetSection(key).Value; } }
(3)在Startup中注册。
// 注入设置类到管道中services.AddOptions();services.Configure(Configuration);// 初始化工具类new AppsettingsUtility(services,Configuration);
(4)使用。
var aa = AppsettingsUtility.GetMonitor().CurrentValue;var bb = AppsettingsUtility.GetSettingsModel();var bb = AppsettingsUtility.GetSetting("Appsetting:xxx");
如果把配置文件改变了,再调用获取设置的时候,设置的值会更新,项目不用重启。这样做对性能的影响没有测试。
如果我这边的思路有什么错误的话,还望批评指出。