扩展步骤
- 实现IConfigurationSource
- 实现IConfigurationProvider
- 实现AddXXX扩展方法
示例
新建控制台应用程序👉命名ConfigurationCustom👉引入包Microsoft.Extensions.Configuration👉新建三个类:MyConfigurationSource.cs、MyConfigurationProvider.cs、MyConfigurationBuilderExtensions.cs
首先,MyConfigurationSource.cs继承接口IConfigurationSource
using Microsoft.Extensions.Configuration;using System;namespace ConfigurationCustom{public class MyConfigurationSource : IConfigurationSource{public IConfigurationProvider Build(IConfigurationBuilder builder){return new MyConfigurationProvider();}}}
MyConfigurationProvider.cs没有直接继承IConfigurationProvider而是继承了抽象类ConfigurationProvider,这个类实际上是继承了IConfigurationProvider
using Microsoft.Extensions.Configuration;using System;using System.Timers;namespace ConfigurationCustom{class MyConfigurationProvider : ConfigurationProvider{private readonly 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);}// 入参表示我们这里是否是重新加载,如果重新加载,我们需要触发OnReload这个方法private void Load(bool reload){Data["lastTime"] = DateTime.Now.ToString();if (reload){OnReload();}}}}
我们继承了ConfigurationProvider之后,键入一些代码,设置一个Timer每3秒将当前时间给Provider,来模拟配置发生变化。
修改Program类
using Microsoft.Extensions.Configuration;using System;namespace ConfigurationCustom{class Program{static void Main(string[] args){var builder = new ConfigurationBuilder();builder.Add(new MyConfigurationSource());var root = builder.Build();Console.WriteLine(root["lastTime"]);}}}
输出:
但是我们这样子去分发我们的配置源的包的话,我们会需要把我们的MyConfigurationSource定义为public的,否则使用方式没办法引用到我们这个类的,那么我们就可以通过扩展方法的方法来保障我们不需要暴露我们的configSource
之前我们创建了类MyConfigurationBuilderExtensions
using ConfigurationCustom;namespace Microsoft.Extensions.Configuration{public static class MyConfigurationBuilderExtensions{public static IConfigurationBuilder AddMyConfiguration(this IConfigurationBuilder builder){builder.Add(new MyConfigurationSource());return builder;}}}
首先我们把这个扩展方法的命名空间,放在了config的命名空间,这样方便我们在引用的时候直接使用。然后把其它两个类定义为internal。如果分发到第三方的话,internal的类是不能被引用的。
之后去使用的话,将Program类的builder.Add(new MyConfigurationSource()修改为builder.AddMyConfiguration()
using Microsoft.Extensions.Configuration;using System;namespace ConfigurationCustom{class Program{static void Main(string[] args){var builder = new ConfigurationBuilder();builder.AddMyConfiguration();var root = builder.Build();Console.WriteLine(root["lastTime"]);}}}
输出:
之前我们学到了要使用ChangeToken的方式来监听配置变化,现在这里一样使用ChangeToken.OnChange
using Microsoft.Extensions.Configuration;using Microsoft.Extensions.Primitives;using System;namespace ConfigurationCustom{class Program{static void Main(string[] args){var builder = new ConfigurationBuilder();builder.AddMyConfiguration();var root = builder.Build();ChangeToken.OnChange(() => root.GetReloadToken(), () =>{Console.WriteLine(root["lastTime"]);});Console.WriteLine("开始监听配置:");Console.ReadKey();}}}
输出:
