首页 > 其他分享 >Configuration

Configuration

时间:2024-09-11 17:51:44浏览次数:1  
标签:string providers source var new Configuration public

ConfigurationRoot

public interface IConfiguration
{
    string? this[string key] { get; }
    IChangeToken GetReloadToken();
}

public interface IConfigurationRoot : IConfiguration
{
    void Reload();
}

public class ConfigurationRoot : IConfigurationRoot
{
    private readonly List<IConfigurationProvider> _providers;
    private readonly IList<IDisposable> _changeTokenRegistrations;
    private ConfigurationReloadToken _changeToken = new ConfigurationReloadToken();

    public ConfigurationRoot(List<IConfigurationProvider> providers)
    {
        this._providers = providers;
        this._changeTokenRegistrations = new List<IDisposable>(providers.Count);
        foreach (IConfigurationProvider p in providers)
        {
            p.Load();
            _changeTokenRegistrations.Add(ChangeToken.OnChange(() => p.GetReloadToken(), () => RaiseChanged()));
        }
    }

    public string? this[string key]
    {
        get
        {
            return GetConfiguration(_providers, key);
        }
    }

    internal static string? GetConfiguration(List<IConfigurationProvider> providers, string key)
    {
        for (var i = providers.Count - 1; i >= 0; i--)
        {
            var provider = providers[i];
            if (provider.TryGet(key, out var value))
            {
                return value;
            }
        }

        return null;
    }

    public IChangeToken GetReloadToken()
    {
        return _changeToken;
    }

    public void Reload()
    {
        foreach (IConfigurationProvider provider in _providers)
        {
            provider.Load();
        }
        RaiseChanged();
    }

    private void RaiseChanged()
    {
        ConfigurationReloadToken previousToken = Interlocked.Exchange(ref _changeToken, new ConfigurationReloadToken());
        previousToken.OnReload();
    }

}

ConfigurationReloadToken

public class ConfigurationReloadToken : IChangeToken
{
    private CancellationTokenSource _cts = new CancellationTokenSource();

    public bool HasChanged => _cts.IsCancellationRequested;

    public bool ActiveChangeCallbacks => true;

    public IDisposable RegisterChangeCallback(Action<object?> callback, object? state) => _cts.Token.Register(callback, state);

    public void OnReload() => _cts.Cancel();
}

ConfigurationSource

public interface IConfigurationSource
{
    IConfigurationProvider Build(IConfigurationBuilder builder);
}

ConfigurationProvider

public interface IConfigurationProvider
{
    bool TryGet(string key, out string? value);

    void Load();

    IChangeToken GetReloadToken();
}

public abstract class ConfigurationProvider : IConfigurationProvider
{
    private ConfigurationReloadToken _reloadToken = new ConfigurationReloadToken();

    protected ConfigurationProvider()
    {
        Data = new Dictionary<string, string?>(StringComparer.InvariantCultureIgnoreCase);
    }

    protected Dictionary<string, string?> Data { get; set; }

    public virtual bool TryGet(string key, out string? value)
    {
        return Data.TryGetValue(key, out value);
    }

    public virtual void Load()
    {

    }

    public IChangeToken GetReloadToken()
    {
        return _reloadToken;
    }

    protected void OnReload()
    {
        ConfigurationReloadToken previousToken = Interlocked.Exchange(ref _reloadToken, new ConfigurationReloadToken());
        previousToken.OnReload();
    }
}

ConfigurationBuilder

public interface IConfigurationBuilder
{
    IConfigurationRoot Build();
}

public class ConfigurationBuilder : IConfigurationBuilder
{
    public IList<IConfigurationSource> Sources { get; } = new List<IConfigurationSource>();

    public IConfigurationBuilder Add(IConfigurationSource source)
    {
        Sources.Add(source);
        return this;
    }

    public IConfigurationRoot Build()
    {
        var providers = new List<IConfigurationProvider>();

        foreach (var source in Sources)
        {
            providers.Add(source.Build(this));
        }

        return new ConfigurationRoot(providers);
    }
}

示例

public class DemoConfigurationSource : IConfigurationSource
{
    public string Path;

    public DemoConfigurationSource(string path)
    {
        Path = path;
    }

    public IConfigurationProvider Build(IConfigurationBuilder builder)
    {
        return new DemoConfigurationProvider(this);
    }

    public Dictionary<string, string> LoadData()
    {
        return File.ReadAllLines(Path)
            .Where(x => !string.IsNullOrWhiteSpace(x) && x.Contains(":"))
            .ToDictionary(x => x.Split(":")[0], x => x.Split(":")[1]);
    }
}

public class DemoConfigurationProvider : ConfigurationProvider
{
    private DemoConfigurationSource _source { get; }

    public DemoConfigurationProvider(DemoConfigurationSource source)
    {
        _source = source;

        var dir = Path.GetDirectoryName(source.Path);
        var fileName = Path.GetFileName(source.Path);
        var provider = new PhysicalFileProvider(dir);

        ChangeToken.OnChange(
            () => provider.Watch(fileName),
            () =>
            {
                Thread.Sleep(5000);
                Load();
                // 通知外部有变动
                OnReload();
            });
    }

    public override void Load()
    {
        Data = _source.LoadData();
    }

    private Dictionary<string, string> LoadData()
    {
        return File.ReadAllLines(_source.Path)
            .Where(x => !string.IsNullOrWhiteSpace(x) && x.Contains(":"))
            .ToDictionary(x => x.Split(":")[0], x => x.Split(":")[1]);
    }
}

public static class DemoConfigurationExtensions
{
    public static IConfigurationBuilder AddDemo(this ConfigurationBuilder builder, string path)
    {
        builder.Add(new DemoConfigurationSource(path));
        return builder;
    }
}

static void Main(string[] args)
{
    //var serviceCollection = new ServiceCollection();

    //var service = serviceCollection.BuildServiceProvider();

    var configurationBuilder = new ConfigurationBuilder();
    configurationBuilder.AddDemo("d://1.txt");

    var configuration = configurationBuilder.Build();

    ChangeToken.OnChange(() => configuration.GetReloadToken(), () =>
    {
        var value = configuration["a1"];
        Console.WriteLine($"a1 = {value}");
    });

    //// 手动触发加载
    //configuration.Reload();

    Console.ReadLine();
}

标签:string,providers,source,var,new,Configuration,public
From: https://www.cnblogs.com/readafterme/p/18408656

相关文章

  • @ConfigurationProperties VS @Value,你觉得哪个更好用
    文章目录使用测试@ConfigurationProperties和@Value区别复杂类型封装松散绑定元数据支持SpEL表达式JSR-303数据校验总结实际工作中,我们经常会看到或用到@ConfigurationProperties和@Value注解来注入自定义配置属性,那它们之间有什么不同呢?本文将从松散绑定、参数校验、SpEL表达......
  • pymongo.errors.ConfigurationError: Server at localhost:27017 reports wire versio
    当你的PyMongo版本比较新时,如当前使用版本为v4.8.0,如果你尝试连接到MongoDBServerv3.4或更早版本,PyMongo可能会引发以下错误:pymongo.errors.ConfigurationError:Serveratlocalhost:27017reportswireversion5,butthisversionofPyMongorequiresatleast6(Mo......
  • 完美解决 org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration
    一、启动SpringBoot框架报错:org.springframework.boot.SpringApplication:Applicationrunfailedjava.lang.IllegalStateException:Errorprocessingconditiononorg.springframework.boot.autoconfigure.cache.CacheAutoConfiguration......二、网上查找了半天信......
  • spark的SparkSubmit类关于Configuration的资源文件加载
    在阅读 SparkSubmit 源代码时,重点关注 Configuration 的资源文件的加载情况,默认通过 newConfiguration() 构造方法创建时,只会加载 core-default.xml 和core-site.xml文件,但是 SparkSubmit 中打印 Configuration 时,发现还会加载 yarn-site.xml,SparkSubmit 代码中没有......
  • spark的SparkSubmit类关于Configuration的资源文件加载
    在阅读 SparkSubmit 源代码时,重点关注 Configuration 的资源文件的加载情况,默认通过 newConfiguration() 构造方法创建时,只会加载 core-default.xml 和core-site.xml文件,但是 SparkSubmit 中打印 Configuration 时,发现还会加载 yarn-site.xml,SparkSubmit 代码中没......
  • net core自定义 Configuration Provider
    创建CustomConfigurationProvider首先,我们需要创建一个自定义的ConfigurationSource和ConfigurationProvider来支持配置文件的读取和监控。publicclassCustomConfigurationSource:IConfigurationSource{publicstringFilePath{get;}publicCustomConfig......
  • 深入解析Spring Boot中的@ConfigurationProperties注解
    深入解析SpringBoot中的@ConfigurationProperties注解在SpringBoot框架中,配置管理是一个核心功能。SpringBoot提供了多种方式来处理外部配置,其中@ConfigurationProperties注解是一个非常强大且灵活的工具。本文将深入探讨@ConfigurationProperties注解的概念、用法、工......
  • docker之pull失败。error pulling image configuration: download failed after attem
    一、问题描述docker部署完成后,想pull项目,但是就是报错:errorpullingimageconfiguration:downloadfailedafterattempts=6:dialtcp108.160.170.26:443:connect:connectionrefused, 更奇葩的是执行dockersearchhello-world是可以的。二、解决问题1)问题分析:看报......
  • Docker 镜像拉取失败(error pulling image configuration:download failed)
     修改daemon.json配置vim/etc/docker/daemon.json 输入i替换为:{"builder":{"gc":{"defaultKeepStorage":"20GB","enabled":true}},"experimental":true,"f......
  • 【已解决】戴尔 Inspiron 5457 和 5557 启动报错:Invalid configuration information -
    场景我使用的是戴尔15-5557的笔记本电脑,在某次开机的时候系统提示:Invalidconfigurationinformation-pleaserunSETUPprogram.虽然的点击Continue可以正常进入系统,但是每次开机都要来上这么一下真的很烦人,于是想着解决一下。试错过程1.BIOS调整刚开始以为是自己BIOS......