前言
默认情况下,用nacos-sdk-csharp集成ASP.NET Core的配置系统,是基于JSON格式的数据。
随着业务系统的多样化,可能用的配置格式也是各有千秋的。有的会用yaml/yml,有的会用ini,有的会用xml,等等。
那么如果我们存在nacos里面的配置数据是非JSON格式的,我们要怎么去适配呢?
老黄在下面为大家一一解答,主要从两个问题点来切入。
集成yaml/yml格式的的配置
定制不同格式的parser
集成yaml/yml格式的的配置
目前最新的稳定版及预览版除了默认的JSON外,还支持yaml/yml和ini两种格式,这里就以yaml/yml为例来说明。
这里会创建一个WebAPI项目来演示,创建好项目后,安装下面两个nuget包
<PackageReference Include="nacos-sdk-csharp-unofficial.Extensions.Configuration" Version="0.5.0" />
<PackageReference Include="nacos-sdk-csharp-unofficial.YamlParser" Version="0.5.0" />
一个是.NET Core的集成包,一个是yaml格式的数据解析包。
public class Program
{public static void Main(string[] args){CreateHostBuilder(args).Build().Run();}public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).ConfigureAppConfiguration((context, builder) =>{var c = builder.Build();// read configuration from config files, and the data type is yaml/ymlbuilder.AddNacosConfiguration(c.GetSection("NacosConfig"),Nacos.YamlParser.YamlConfigurationStringParser.Instance);}).ConfigureWebHostDefaults(webBuilder =>{webBuilder.UseStartup<Startup>();});
}
还要先配置nacos相关的内容。
{"NacosConfig": {"Optional": false,"DataId": "yamlconfigdemo","Group": "","Tenant": "f47e0ae1-982a-4a64-aea3-52506492a3d4","ServerAddresses": [ "http://localhost:8848/" ],"UserName": "","Password": "","AccessKey": "","SecretKey": "","EndPoint": ""}
}
后面是定义配置的映射类,这一步是可选的,目的是为了使用配置的时候可以点出来。
public class AppSettings
{public string Str { get; set; }public int Num { get; set; }public List<int> Arr { get; set; }public SubObj SubObj { get; set; }
}public class SubObj
{public string a { get; set; }
}
要映射,别忘了在Startup里面加这一句。
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
然后是控制器读配置。
[ApiController]
[Route("api/[controller]")]
public class ConfigController : ControllerBase
{private readonly ILogger<ConfigController> _logger;private readonly IConfiguration _configuration;private readonly AppSettings _settings;private readonly AppSettings _sSettings;private readonly AppSettings _mSettings;public ConfigController(ILogger<ConfigController> logger,IConfiguration configuration,IOptions<AppSettings> options,IOptionsSnapshot<AppSettings> sOptions,IOptionsMonitor<AppSettings> _mOptions){_logger = logger;_configuration = configuration;_settings = options.Value;_sSettings = sOptions.Value;_mSettings = _mOptions.CurrentValue;}[HttpGet]public string Get(){string id = Guid.NewGuid().ToString("N");_logger.LogInformation($"============== begin {id} =====================");var conn = _configuration.GetConnectionString("Default");_logger.LogInformation($"{id} conn = {conn}");var version = _configuration["version"];_logger.LogInformation($"{id} version = {version}");var str1 = Newtonsoft.Json.JsonConvert.SerializeObject(_settings);_logger.LogInformation($"{id} IOptions = {str1}");var str2 = Newtonsoft.Json.JsonConvert.SerializeObject(_sSettings);_logger.LogInformation($"{id} IOptionsSnapshot = {str2}");var str3 = Newtonsoft.Json.JsonConvert.SerializeObject(_mSettings);_logger.LogInformation($"{id} IOptionsMonitor = {str3}");_logger.LogInformation($"===============================================");return "ok";}
}
因为这个配置不是可选的,所以在启动应用之前,要添加下面的配置在nacos里面,不然启动是会报错的。
具体配置示例如下:
ConnectionStrings: Default: Server=127.0.0.1;Port=3306;Database=demo;User Id=root;Password=123456;
version: 测试version
AppSettings: Str: valnum: 1arr: - 1- 2- 3subobj: a: b
运行并访问 http://localhost:5000/api/config
,我们可以看到程序的日志输出,是能正常拿到配置的数据的。
这也就是说,我们的程序已经可以正常读取Yaml格式的配置了。
再来看看修改之后能不能及时获取到最新的配置。
修改后再访问一次。
从结果看,也是能及时获取到最新的配置。
就目前来说,JSON,yaml/yml,ini格式的数据应该能满足60%~80%左右的需求,如果遇到一个“新格式”,我们要怎么做呢?
下面来具体看看。
定制自己的parser
在Nacos客户端里面,定义了一个名为INacosConfigurationParser
的接口,具体如下:
public interface INacosConfigurationParser
{IDictionary<string, string> Parse(string input);
}
这个接口里面也只有一个方法,这个方法的目的就是把字符串类型的配置,转化成一个键值对,从而让.NET Core的配置系统能够识别出来。
下面来个不完整的例子:
public class XmlConfigurationStringParser : INacosConfigurationParser
{public static XmlConfigurationStringParser Instance = new XmlConfigurationStringParser();public IDictionary<string, string> Parse(string input){// 具体的解析逻辑}
}
实现好自己的parser之后,就可以在Program里面去指定这个parser了。
// builder.AddNacosConfiguration(
// c.GetSection("NacosConfig"),
// Nacos.YamlParser.YamlConfigurationStringParser.Instance);builder.AddNacosConfiguration(
c.GetSection("NacosConfig"),
XmlConfigurationStringParser.Instance);
这个时候就会使用XmlConfigurationStringParser
去解析配置了。
总结
有了这个特性之后,基本上只要能把对应格式的数据正常解析,就能很好的集成到ASP.NET Core里面了。
如果nacos控制台里面的配置格式没有我们需要的,我们可以直接配置成TEXT格式,这个是不影响我们使用的,只是显示的时候没那么直观。
最后,如果您对 nacos-sdk-csharp 这个项目感兴趣,可以加入我们一起来完善哟,issue,PR都ok的。
nacos 2.x版本可能会引用grpc或rsocket进行长链接的改造,到时sdk这边可能也会是一个比较有意思的改进。
项目地址:
https://github.com/nacos-group/nacos-sdk-csharp