扩展步骤

  • 实现IConfigurationSource
  • 实现IConfigurationProvider
  • 实现AddXXX扩展方法

示例

新建控制台应用程序👉命名ConfigurationCustom👉引入包Microsoft.Extensions.Configuration👉新建三个类:MyConfigurationSource.csMyConfigurationProvider.csMyConfigurationBuilderExtensions.cs

首先,MyConfigurationSource.cs继承接口IConfigurationSource

  1. using Microsoft.Extensions.Configuration;
  2. using System;
  3. namespace ConfigurationCustom
  4. {
  5. public class MyConfigurationSource : IConfigurationSource
  6. {
  7. public IConfigurationProvider Build(IConfigurationBuilder builder)
  8. {
  9. return new MyConfigurationProvider();
  10. }
  11. }
  12. }

MyConfigurationProvider.cs没有直接继承IConfigurationProvider而是继承了抽象类ConfigurationProvider,这个类实际上是继承了IConfigurationProvider

  1. using Microsoft.Extensions.Configuration;
  2. using System;
  3. using System.Timers;
  4. namespace ConfigurationCustom
  5. {
  6. class MyConfigurationProvider : ConfigurationProvider
  7. {
  8. private readonly Timer _timer;
  9. public MyConfigurationProvider() : base()
  10. {
  11. _timer = new Timer();
  12. _timer.Elapsed += _timer_Elapsed;
  13. _timer.Interval = 3000;
  14. _timer.Start();
  15. }
  16. private void _timer_Elapsed(object sender, ElapsedEventArgs e)
  17. {
  18. Load(true);
  19. }
  20. // 重写基类方法加载数据
  21. public override void Load()
  22. {
  23. Load(false);
  24. }
  25. // 入参表示我们这里是否是重新加载,如果重新加载,我们需要触发OnReload这个方法
  26. private void Load(bool reload)
  27. {
  28. Data["lastTime"] = DateTime.Now.ToString();
  29. if (reload)
  30. {
  31. OnReload();
  32. }
  33. }
  34. }
  35. }

我们继承了ConfigurationProvider之后,键入一些代码,设置一个Timer每3秒将当前时间给Provider,来模拟配置发生变化。
修改Program

  1. using Microsoft.Extensions.Configuration;
  2. using System;
  3. namespace ConfigurationCustom
  4. {
  5. class Program
  6. {
  7. static void Main(string[] args)
  8. {
  9. var builder = new ConfigurationBuilder();
  10. builder.Add(new MyConfigurationSource());
  11. var root = builder.Build();
  12. Console.WriteLine(root["lastTime"]);
  13. }
  14. }
  15. }

输出:image.png
但是我们这样子去分发我们的配置源的包的话,我们会需要把我们的MyConfigurationSource定义为public的,否则使用方式没办法引用到我们这个类的,那么我们就可以通过扩展方法的方法来保障我们不需要暴露我们的configSource
之前我们创建了类MyConfigurationBuilderExtensions

  1. using ConfigurationCustom;
  2. namespace Microsoft.Extensions.Configuration
  3. {
  4. public static class MyConfigurationBuilderExtensions
  5. {
  6. public static IConfigurationBuilder AddMyConfiguration(this IConfigurationBuilder builder)
  7. {
  8. builder.Add(new MyConfigurationSource());
  9. return builder;
  10. }
  11. }
  12. }

首先我们把这个扩展方法的命名空间,放在了config的命名空间,这样方便我们在引用的时候直接使用。然后把其它两个类定义为internal。如果分发到第三方的话,internal的类是不能被引用的。
之后去使用的话,将Program类的builder.Add(new MyConfigurationSource()修改为builder.AddMyConfiguration()

  1. using Microsoft.Extensions.Configuration;
  2. using System;
  3. namespace ConfigurationCustom
  4. {
  5. class Program
  6. {
  7. static void Main(string[] args)
  8. {
  9. var builder = new ConfigurationBuilder();
  10. builder.AddMyConfiguration();
  11. var root = builder.Build();
  12. Console.WriteLine(root["lastTime"]);
  13. }
  14. }
  15. }

输出:image.png

之前我们学到了要使用ChangeToken的方式来监听配置变化,现在这里一样使用ChangeToken.OnChange

  1. using Microsoft.Extensions.Configuration;
  2. using Microsoft.Extensions.Primitives;
  3. using System;
  4. namespace ConfigurationCustom
  5. {
  6. class Program
  7. {
  8. static void Main(string[] args)
  9. {
  10. var builder = new ConfigurationBuilder();
  11. builder.AddMyConfiguration();
  12. var root = builder.Build();
  13. ChangeToken.OnChange(() => root.GetReloadToken(), () =>
  14. {
  15. Console.WriteLine(root["lastTime"]);
  16. });
  17. Console.WriteLine("开始监听配置:");
  18. Console.ReadKey();
  19. }
  20. }
  21. }

输出:image.png