.Net 4.X 提前用上 .Net Core 的配置模式以及热重载配置

1. 前言

在提倡微服务及 Serverless 越来越普及的当下,传统 .Net 应用的配置模式往往依赖于一个名为 web.config 的 XML 文件,在可扩展性和可读性与时代脱节了。当然,我不会怂恿一下子把所有应用迁移到 .Net Core 上,本文将在尽量不引入 .Net Core 开发模式的前提下,获得最大的利益。

在开始之前,我们还是先说说 .Net Core 的配置模式有何优势以及最少的依赖。

1.1 .Net Core 配置模式的优势

  • 支持多种格式,如 Json、ini、Yaml、系统环境变量等

  • 不再依赖于 web.config ,可同时使用多种配置格式

  • 支持热重载配置,修改配置可以不用重启应用

1.2 最少依赖

nuget install  Microsoft.Extensions.Configurationnuget install Microsoft.Extensions.Configuration.Binder
nuget install Castle.Windsor (其他 IOC 框架均可)

如果你安装的是最新的包,可能会遇到 Microsoft.Extensions.Configuration 系列 Nuget 包无法安装的问题,这主要取决当前应用的 .Net 版本,请参考下图,安装对应的版本(目前不支持 .Net 4.5 以下的应用)。

由于本人喜欢可读性高的 Json 文件,所以还安装 Microsoft.Extensions.Configuration.Json 的 Nuget 包。

2. 示例教程

本文在 Abp 2.1.3 的基础上实现 .Net Core 的配置模式以及热重载配置,更详细的过程可参照我在 Github 上的 提交历史 。

2.1 加载配置

.Net Core 配置模式的核心是一个名为 IConfigurationRoot 的接口对象,需要在应用入口中加载各种配置格式后创建一个 IConfigurationRoot 的实例,在传统的 .Net Web 应用中是在 Global.asax.cs 中赋值。

// ConfigurationExtenion.AppConfiguration 为一个静态的 IConfigurationRoot 实例。ConfigurationExtenion.AppConfiguration = new ConfigurationBuilder().AddJsonFile("appsetting.json", optional: false, reloadOnChange: true).AddJsonFile("appsetting01.json", optional: true, reloadOnChange: false).Build();

简单地解释一下,我们需要(在根目录中) 有一个名为 "appsetting.json" 的 Json 文件,被修改的同时会重载 ConfigurationExtenion.AppConfiguration 。与之相反的 "appsetting01.json" 则允许不存在,即使存在,被修改时不会重载配置。

2.2 读取配置节点

加载配置后,我们需要把配置读取出来,在 IConfigurationRoot 中所有配置的信息都是存在于一个个节点中,我们可以根据节点名称来获取对应的类型对象。

        /// <summary>/// 获取节点配置/// </summary>/// <typeparam name="TService"></typeparam>/// <param name="config"></param>/// <param name="sectionName"></param>/// <returns></returns>internal static TService GetSectionObject<TService>(IConfigurationRoot config, String sectionName){            var section = config.GetSection(sectionName);            if (section == null){                throw new ArgumentException($" {sectionName} 未绑定,无法获取到配置节点信息!");}            return section.Get<TService>();}

假设我们有一个这样的 "appsetting.json" 文件:

{"RedisConfiguration": {"InstanceDbId": 14,"InstanceRedisConnectionString": "127.0.0.1"},"MongoDbConfiguration": {"ConnectionString": "mongodb://127.0.0.1:27017/?connectTimeoutMS=300000","DatatabaseName": "local"}}

如果我们要获取 MongoDbConfiguration 下的 ConnectionString 的值,那么我们可以这样获取:

var connectionString= GetSectionObject<String>(ConfigurationExtenion.AppConfiguration,"MongoDbConfiguration:ConnectionString");

2.3 设计配置类

在传统的 .Net 应用程序中,我们往往会使用一个静态变量去存放配置信息。而在有 IOC 的情况下,更好的方法是设计一个类来存放配置,如上面的 Json 文件我们可以设计如下两个类(在 Visual Studio 选择性黏贴 Json 会自动生成对象):

    public class RedisConfiguration{        public int InstanceDbId { get; set; }        public string InstanceRedisConnectionString { get; set; }}    public class MongodbConfiguration{        public string ConnectionString { get; set; }        public string DatatabaseName { get; set; }}

2.4 注册配置

为了实现热重载配置,而不是一层不变的值,我们在 IOC 中获取配置类时,需要使用工厂方法获取。在 Windsor 中可以这么做:

        /// <summary>/// 注册方法/// </summary>/// <typeparam name="TService"></typeparam>/// <param name="ioc"></param>/// <param name="factoryMethod"></param>private static void Register<TService>(IIocManager ioc, Func<TService> factoryMethod) where TService : class{ioc.IocContainer.Register(Component.For<TService>().UsingFactoryMethod(factoryMethod).LifestyleTransient() //这里的生命周期是瞬时的,单例不可以吗?);}

结合前面的获取配置节点,我们可以把两个静态方法组合起来创造一个新的静态方法,更方便我们使用。

        /// <summary>/// 注册配置/// </summary>/// <typeparam name="TService"></typeparam>/// <param name="ioc"></param>/// <param name="config"></param>/// <param name="sectionName"></param>internal static void InitConfigService<TService>(IIocManager ioc, IConfigurationRoot config, String sectionName) where TService : class{Register(ioc, () =>{                var service = GetSectionObject<TService>(config, sectionName);                return service;});}

对于前面两个配置类,我们可以这样注入:

   ConfigurationExtenion.InitConfigService<RedisConfiguration>(IocManager,ConfigurationExtenion.AppConfiguration, "RedisConfiguration");   ConfigurationExtenion.InitConfigService<MongodbConfiguration>(IocManager, ConfigurationExtenion.AppConfiguration, "MongoDbConfiguration");

2.5 获取配置

我在这里新增一个控制器方法获取 RedisConfiguration 对象,该方法使用属性注入获取指定的配置类,并返回给页面。

       public String GetRedisConfig()        {            var redisConfig = IocManager.Instance.Resolve<RedisConfiguration>();            return redisConfig.ToJsonString();}

可以看到页面显示的与 Json 文件中结构一模一:

2.6 热重载配置

与 .Net Core 不一样,在 .Net 4.X 的 Web 应用中只是稍微修改下 Json 文件都会让整个应用重启(修改 web.config 同样会重启),所以我将 "appsetting.json" 重命名为 "appsetting.conf" ,在运行时修改某些值,并重新访问控制器,可以看到对应的值变了。

需要注意 IIS 的安全配置,Json 或者 ini 也许能直接通过 HTTP 获取!

3. 结语

通过简单的使用 .Net Core 配置模式,我们可以感受到其强大魅力,如果你对 .Net Core 更多的了解,以及感受两者的对比,可以对照我之前写过的一篇文章。对于热重载配置,.Net Core 中更多是使使用IOptionsSnapshot,而为了尽量少地引入 .Net Core 的特性,在这里只是简单地用了 IOC 的特性。当然,在不使用任何 IOC 的情况下(如果你害怕引入 IOC ),定义一个 IConfigurationRoot 的全局静态实例,也不失为一个折中的方案。

原文:https://www.cnblogs.com/chenug/p/8525727.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/321988.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# 枚举特性 FlagAttribute 的应用

写在前面枚举Enum 全称(Enumeration)&#xff0c;即一种由一组称为枚举数列表的命名常量组成的独特类型。可以看出枚举的出现是为了使我们可以在程序中方便的使用一些特定值的常量&#xff0c;一般的使用大家都比较熟悉&#xff0c;本文主要介绍枚举的特性 FlagAttribute。Flag…

重温.NET下Assembly的加载过程

最近在工作中牵涉到了.NET下的一个古老的问题&#xff1a;Assembly的加载过程。虽然网上有很多文章介绍这部分内容&#xff0c;很多文章也是很久以前就已经出现了&#xff0c;但阅读之后发现&#xff0c;并没能解决我的问题&#xff0c;有些点写的不是特别详细&#xff0c;让人…

看eShopOnContainers学一个EventBus

最近在看微软eShopOnContainers 项目&#xff0c;看到事件总线觉得不错&#xff0c;和大家分享一下看完此文你将获得什么&#xff1f;eShop中是如何设计事件总线的实现一个InMemory事件总线eShop中是没有InMemory实现的&#xff0c;这算是一个小小小的挑战发布订阅模式发布订阅…

创建基于MailKit和MimeKit的.NET基础邮件服务

邮件服务是一般的系统都会拥有和需要的功能&#xff0c;但是对于.NET项目来说&#xff0c;邮件服务的创建和使用会较为的麻烦。.NET对于邮件功能提供了System.Net.Mail用于创建邮件服务&#xff0c;该基础服务提供邮件的基础操作&#xff0c;并且使用也较为的简单。对于真正将该…

EF Core下利用Mysql进行数据存储在并发访问下的数据同步问题

小故事在开始讲这篇文章之前&#xff0c;我们来说一个小故事&#xff0c;纯素虚构&#xff08;真实的存钱逻辑并非如此&#xff09;小刘发工资后&#xff0c;赶忙拿着现金去银行&#xff0c;准备把钱存起来&#xff0c;而与此同时&#xff0c;小刘的老婆刘嫂知道小刘的品性&…

牛客练习赛50-记录

正题 比赛链接:https://ac.nowcoder.com/acm/contest/1080#question 成绩 本届 升高二届 总结 以后还是不要写太多自己不擅长的写法&#xff0c;空间要多检查&#xff0c;不要像个傻逼一样啥都写错。 尽量不要为了省一点空间和时间写一些不舒服的东西&#xff0c;尽量在能…

物联网框架ServerSuperIO在.NetCore实现跨平台的实践路线

正所谓天下大势&#xff0c;不跟风不行。你不跨平台&#xff0c;很low嘛。java说&#xff1a;你们能跨嘛&#xff0c;跨给我看看。C#说&#xff1a;不要强人所难嘛。java说&#xff1a;能部署在云上吗&#xff1f;docker&#xff1f;微服务&#xff1f;C#说&#xff1a;不要强人…

使用WebApiClient请求和管理Restful Api

前言本篇文章的内容是WebApiClient应用说明篇&#xff0c;如果你没有了解过WebApiClient&#xff0c;可以先阅读以下相关文章&#xff1a;WebApi client 的面向切面编程我来给.Net设计一款HttpClient.Net45下HttpClient的几个缺陷.net的retrofit--WebApiClient库.net的retrofit…

拥抱.NET Core系列:MemoryCache 缓存选项

MSCache项目MSCache 目前最新的正式版是 2.0.0&#xff0c;预览版是2.1.0&#xff0c;会与 .NETCore 2.1 一起发布。本篇用了2.0.0版本开源在 GitHub 上&#xff0c;仓库地址是&#xff1a;https://github.com/aspnet/CachingNuGet地址为&#xff1a;https://www.nuget.org/pac…

牛客练习赛51-记录

正题 比赛链接:https://ac.nowcoder.com/acm/contest/1083#question 成绩 可怜的zycT3zycT3zycT3被n0n0n0卡了半天&#xff0c;这里感谢一下排雷 总结 比赛状态较好&#xff0c;后面没有T6T6T6的题解 T1:abcT1:abcT1:abc 题目大意 给出一个字符串&#xff0c;求有多少个abc…

Metrics.net + influxdb + grafana 构建WebAPI的自动化监控和预警

前言这次主要分享通过Metrics.net influxdb grafana 构建WebAPI的自动化监控和预警方案。通过执行耗时&#xff0c;定位哪些接口拖累了服务的性能&#xff1b;通过请求频次&#xff0c;设置适当的限流和熔断机制&#xff0c;拦截非法或不合理的请求&#xff0c;保障服务的可用…

EF Core 2.1路线图:视图、GROUP BY和惰性加载

Entity Framework Core一直追随着初始Entity Framework的发展&#xff0c;并不断推陈出新。它首先推出的是对视图的支持&#xff0c;这听起来有些耸人听闻。在即将推出的EF Core 2.1之前&#xff0c;EF Core并未对数据库视图提供官方的支持&#xff0c;也不支持缺少主键的数据库…

计算机网络总结

一、计算机网络体系 &#xff08;1&#xff09;OSI分层 &#xff08;7层&#xff09; 物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。 &#xff08;2&#xff09;TCP/IP分层&#xff08;4层&#xff09; 网络接口层、 网际层、运输层、 应用层。 &#xff0…

从技术角度讨论微服务

本文希望从技术角度来探讨下微服务&#xff0c;因此&#xff0c;不会过多地谈及如何根据业务进行微服务划分&#xff0c;更多是介绍微服务的相关技术&#xff0c;微服务的业务划分方法可参考“领域驱动设计“相关方法论。微服务的两个程度一、服务化复杂的单体架构会有以下的挑…

jzoj6344-[NOIP2019模拟2019.9.7]Huge Counting【组合数,状压dp】

正题 题目大意 定义函数f(x)(xf(x)(xf(x)(x为一个序列))) 若任意一个xi1x_i1xi​1那么有f(x)1f(x)1f(x)1 若有一个xi0x_i0xi​0那么有f(x)0f(x)0f(x)0 其他的&#xff0c;有f(x)(∑j1nf(x1...,xj−1,...xn))%2f(x)(\sum_{j1}^nf(x_{1}...,x_j-1,...x_n))\% 2f(x)(j1∑n​f(x1​…

拥抱.NET Core系列:MemoryCache 缓存域

MSCache项目MSCache 目前最新的正式版是 2.0.0&#xff0c;预览版是2.1.0&#xff0c;会与 .NETCore 2.1 一起发布。本篇用了2.0.0版本开源在 GitHub 上&#xff0c;仓库地址是&#xff1a;https://github.com/aspnet/CachingNuGet地址为&#xff1a;https://www.nuget.org/pac…

牛客小白月赛17-记录(附题解)

正题 比赛链接:https://ac.nowcoder.com/acm/contest/1085#question 成绩 总结 除了那道积分数学其他还好 后面没有FFF题的题解 T1:小sun的假期T1:小sun的假期T1:小sun的假期 题目大意 长度为nnn的序列&#xff0c;mmm个区间&#xff0c;求最大的没有被任何区间覆盖的区间…

安全、高效的MySQL DDL解决方案

MySQL作为目前应用最广泛的开源关系型数据库&#xff0c;是许多网站、应用和商业产品的主要数据存储。在生产环境&#xff0c;线上数据库常常面临着持续的、不断变化的表结构修改&#xff08;DDL&#xff09;&#xff0c;如增加、更改、删除字段和索引等等。其中一些DDL操作在M…

DNS总结

一、DNS &#xff08;1&#xff09;简介 域名系统&#xff08;英文&#xff1a;Domain Name System&#xff0c;缩写&#xff1a;DNS&#xff09;是互联网的一项服务。它作为将域名和IP地址相互映射的一个分布式数据库&#xff0c;能够使人更方便地访问互联网。 DNS 协议也是…

谈谈在.NET Core中使用Redis和Memcached的序列化问题

前言在使用分布式缓存的时候&#xff0c;都不可避免的要做这样一步操作&#xff0c;将数据序列化后再存储到缓存中去。序列化这一操作&#xff0c;或许是显式的&#xff0c;或许是隐式的&#xff0c;这个取决于使用的package是否有帮我们做这样一件事。本文会拿在.NET Core环境…