实现自定义的配置框架,主要是要实现IConfigurationSource和IConfigurationProvider接口,这个我们之前提到过,这两个接口是配置框架的扩展点。
IConfigureSource
该接口包括一个Build方法,用来产生IConfigurationProvider,入参是IConfigurationBuilder。
IConfigurationProvider
我们一般不直接实现该接口,而是继承实现了该接口的ConfigurationProvider抽象类,该类做了一些扩展,我们可以通过重写该抽象类的方法来定义我们的配置提供程序(ConfigurationProvider)
如下,我们定义一个MyConfigurationProvider类,类继承了抽象类ConfigurationProvider,并重写了基类的Load方法,我们在类中定义了一个Load(bool reload)方法,当reload=true时则重新加载;在构造函数中通过Timer控制,每3秒调用一个Load(true),并将最新的time赋值给Data["time"],Data是Provider提供的一个key-value字典,用于存储数据。
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); } private void Load(bool reload) { this.Data["time"] = System.DateTime.Now.ToString(); if (reload) { base.OnReload(); } } }
IConfigurationProvider定义好了之后,我们就可以定义IConfigurationSource实现了。
其实,MyConfigurationSource很简单,如上所述,就一个方法
class MyConfigurationSource : IConfigurationSource { public IConfigurationProvider Build(IConfigurationBuilder builder) { return new MyConfigurationProvider(); } }
这样,我们的ConfigurationSource和ConfigurationProvider就定义完成了,下面就可以开始调用了,我们在Program中,按照配置的开启方式来开启我们的自定义配置数据源
configurationBuilder.Add(new MyConfigurationSource());
为了使代码结构更加合理,和之前一样,我们对MyConfigurationSource类进行封装,定义一个MyConfigurationSourceExtension的扩展类,具体如下
public static class MyConfigurationSourceExtension { public static IConfigurationBuilder AddSource( this IConfigurationBuilder configurationBuilder) { MyConfigurationSource myConfigurationSource = new MyConfigurationSource(); configurationBuilder.Add(myConfigurationSource); return configurationBuilder; } }
这样做的好处之前也提到过,就是可以避免将具体的自定义实现完全暴露。
那么,到这里,我们自定义配置数据源的构建差不多就结束了,但是要运行,我们还缺少输出程序,我们每3秒更新一个time来输出,就类似于模拟配置的变更,那么,我们需要用ChangeToken.OnChange来监听配置的变更,并在其中定义我们的回调程序,这里我们直接输出最新的时间。这样,就可以完整模拟自定义配置数据源的过程了,program.cs的代码如下
static void Main(string[] args) { IConfigurationBuilder configurationBuilder = new ConfigurationBuilder(); //configurationBuilder.Add(new MyConfigurationSource()); configurationBuilder.AddSource(); IConfigurationRoot configurationRoot= configurationBuilder.Build(); ChangeToken.OnChange(()=> configurationRoot.GetReloadToken(), () => { Console.WriteLine(configurationRoot["time"]); }); Console.ReadKey(); }
好了,到这里本篇就要结束了,其实自定义配置数据源还是蛮简单的,主要的是要理解配置框架的主要接口及其主要的扩展点,通过自带配置框架的工作过程来理解并实现我们自定义配置数据源的实现就会很简单,而且反过来也有助于理解配置框架的工作过程。
对于这些基本的框架类东西,有时间的话还是动手敲一下,有助于加深理解,大佬就略过吧。
源码可访问
https://github.com/IronMarmot/Samples/tree/master/CoreSamples