14 | custom configuration data source: low cost solutions customized configuration
This section explains how to define your own data sources to extend the configuration framework
Expansion step
1, 实现 IConfigurationSource
2, 实现 IConfigurationProvider
3, to achieve AddXXX extension method, as a shortcut for injection
Source link:
https://github.com/witskeeper/geektime/tree/master/samples/ConfigurationCustom
First, the definition of a MyConfigurationSource
namespace ConfigurationCustom
{
class MyConfigurationSource : IConfigurationSource
{
public IConfigurationProvider Build(IConfigurationBuilder builder)
{
return new MyConfigurationProvider();
}
}
}
Followed by MyConfigurationProvider
namespace ConfigurationCustom
{
// ConfigurationProvider 集成自 IConfigurationProvider
class MyConfigurationProvider : ConfigurationProvider
{
Timer timer;
public MyConfigurationProvider() : base()
{
// 用一个线程模拟配置发生变化,每三秒钟执行一次,告诉我们要重新加载配置
timer = new Timer();
timer.Elapsed += Timer_Elapsed;
timer.Interval = 3000;
timer.Start();
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e) => Load(true);
public override void Load() => Load(false);
/// <summary>
/// 加载数据
/// </summary>
/// <param name="reload">是否重新加载数据</param>
void Load(bool reload)
{
// Data 表示 Key-value 数据,这是由 ConfigurationProvider 提供的一个数据承载的集合
// 我们把最新的时间填充进去
Data["lastTime"] = DateTime.Now.ToString();
if (reload)
{
base.OnReload();
}
}
}
}
Indeed this expansion has been completed, the source can be injected in through this method builder.AddXXX
namespace ConfigurationCustom
{
class Program
{
static void Main(string[] args)
{
var builder = new ConfigurationBuilder();
builder.Add(new MyConfigurationSource());
var configRoot = builder.Build();
Console.WriteLine($"lastTime:{configRoot["lastTime"]}");
Console.ReadKey();
}
}
}
Start the program, the output is as follows:
lastTime:2020/3/1 22:39:36
Here you can see, the output of the latest time
But if such a configuration package to the distribution source, then, need to MyConfigurationSource
defined as public, otherwise no way to use a reference to this class
Then it can be ensured by way of extension methods do not require exposure ConfigSource
Define an extension method AddMyConfiguration
namespace Microsoft.Extensions.Configuration
{
public static class MyConfigurationBuilderExtensions
{
public static IConfigurationBuilder AddMyConfiguration(this IConfigurationBuilder builder)
{
builder.Add(new MyConfigurationSource());
return builder;
}
}
}
First, the namespace extension method on the namespace config, rather than their own namespace, so easy to use when referring directly without the need to load a specific namespace
Another Provider can be defined as internal, the default is internal, if distributed to a third party, then, internal class is not referenced, so that means an extension method only needs to be exposed, without having to expose specific configuration source implementation
class MyConfigurationProvider : ConfigurationProvider
How to use it, it is actually very simple
Only need to use builder.AddMyConfiguration in builder.Add when you can, so to achieve the same effect
namespace ConfigurationCustom
{
class Program
{
static void Main(string[] args)
{
var builder = new ConfigurationBuilder();
//builder.Add(new MyConfigurationSource());
builder.AddMyConfiguration();
var configRoot = builder.Build();
Console.WriteLine($"lastTime:{configRoot["lastTime"]}");
Console.ReadKey();
}
}
}
Start the program, the output is as follows:
lastTime:2020/3/1 22:55:11
In the definition of the extended time, are recommended to do so, the specific implementation are defined as private, and then by way of extension methods exposed to
Just change actually defines a timer to simulate the configuration, where you can monitor what changes it to see if the entry into force
On a ChangeToken mentioned manner, there is a method ChangeToken the OnChange
namespace ConfigurationCustom
{
class Program
{
static void Main(string[] args)
{
var builder = new ConfigurationBuilder();
builder.AddMyConfiguration();
var configRoot = builder.Build();
ChangeToken.OnChange(() => configRoot.GetReloadToken(), () =>
{
Console.WriteLine($"lastTime:{configRoot["lastTime"]}");
});
Console.WriteLine("开始了");
Console.ReadKey();
}
}
}
Start the program, the output is as follows:
开始了
lastTime:2020/3/1 22:59:25
lastTime:2020/3/1 22:59:28
lastTime:2020/3/1 22:59:31
Output once every three seconds, indicating that the notification of configuration changes have taken effect we define
MyConfigurationProvider we just configured to simulate a DateTime source via assignment
In fact, it can be remotely, such as Apollo's distribution center, Kazoo, where remote reading configuration, combined with the command-line and environment variables configuration, the configuration can be done remotely program the center, means that the version of the management configuration
In this way Docker container environment below, Kubernetes environment below, you can have a complete configuration management solution
This work is Creative Commons Attribution - NonCommercial - ShareAlike 4.0 International License Agreement for licensing.
Welcome to reprint, use, repost, but be sure to keep the article signed by Zheng Ziming (containing links: http://www.cnblogs.com/MingsonZheng/), shall not be used for commercial purposes, be sure to publish the same work based on the paper license modification .
If you have any questions, please contact me ([email protected]).