组态设定设计
小明收到需求, 需要在系统中不同环境中设定特别组态,
然后系统依照组态设定去执行不同的动作.
public string GetSetting(string key) { return ConfigurationManager.AppSettings[key] ?? "";}public void Perform() { if( GetSetting("isCountDownEnabled") == "y" ) { ... } var time = DateTime.Parse(GetSetting("OpenTime")); ...}
这段程式很清楚在尝试读取 "isCountDownEnabled", "OpenTime" 的内容,
然后去做一些事情.
首先这程式有个缺点, 就是组态读取的方式是动态类型, 读取出来的值是弱类型.
弱类型, 是指类型检查更不严格, 如偏向于容忍隐式类型转换.
譬如说"isCountDownEnabled" 这个是因为字串很容易打错字, 导致开发人员不小心没有读取到组态.
而且读取出来的Value 内容比对判断方式是 "y" 也可以是 "Y", 甚至其他内容,
这样的结果是容易产生forbidden behaviours.
几乎每个专案都有一些需要根据环境配置和更改的设定,
典型的例子是大多数人都会在 .config 档案中 的区段加上key 和 value
<configuration> <appSettings> <add key="IsCountDownEnabled" value="y"/> <add key="OpenTime" value="2019/08/01"/> </appSettings></configuration>
设计守则 为组态设定建立一个强类型物件
建议的方法是创建一个强类型配置物件, 其结构与组态配置文件中的某个部分(或从中加载配置的任何位置) 匹配, 像
public class MySettings{ public bool IsCountDownEnabled { get; set; } public DateTime OpenTime { get; set; }}
它将映设到 .config 档案中的 appSettings 区段. 组态设定档案可以按照你喜好
放在 web.config 或是其他外部档案. (例如: D:\Configs\MySettings.xml)
MySettings.xml 档案示範内容
<configuration> <MySettings> <IsCountDownEnabled>y</IsCountDownEnabled> <OpenTime>2019/08/01</OpenTime> </MySettings></configuration>
为了确保您的 config 设定内容绑定到 MySettings 物件, 你需要做两件事.
设置ConfigurationBuilder 加载组态设定档案var builder = new ConfigurationBuilder();
将您的组态物件绑定到配置部分你需要使用nuget 引用Microsoft.Extensions.Configuration.Xml
builder.AddXmlFile("MySettings.xml", optional: true, reloadOnChange: true);
最后再透过 Build() 来建立
var configuration = builder.Build();
然后再用configuration 去绑定你的MySettings 组态物件
var myConfig = new MySettings();configuration.GetSection("MySettings").Bind(myConfig);if (myConfig.IsCountDownEnabled == true){ ...}
它可以载入 *.ini, *.json, *.xml 档案, 上面的程式码是加入 xml 的例子, 你可以使用 AddIniFile() 或 AddJsonFile() 来加入不同的档案.
自订组态档案来源
又或者您不希望把设定内容放在到 config 档案中, 改放到自己定义的资料库中.
你也只需要做两件事情
建立 IConfigurationSource 来源public class MyAppSettingDbConfigSource : IConfigurationSource{ public IConfigurationProvider Build(IConfigurationBuilder builder) { return new MyAppSettingDbConfigurationProvider(); }}
建立 Configuration 自订提供者public class MyAppSettingDbConfigurationProvider : ConfigurationProvider{ public override void Load() { //将你资料库的内容读取出来, 放入对应的资料 Data["MySettings:IsCountDownEnabled"] = "y"; Data["MySettings:OpenTime"] = "2019/08/01"; base.Load(); }}
实作完自订的组态来源提供者之后, 透过下面程式码就可以载入自订来源
var builder = new ConfigurationBuilder();builder.Add(new MyAppSettingDbConfigSource());
上述Configuration 机制来源是Microsoft.Extensions.Configuration 提供的, 并非只设计在 AspNetCore 之下.这个Configuration 是可以让广泛的.net 程式所使用, 不侷限于ASP.NET Core.