千家信息网

.Net Core怎么配置Configuration

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章主要介绍".Net Core怎么配置Configuration",在日常操作中,相信很多人在.Net Core怎么配置Configuration问题上存在疑惑,小编查阅了各式资料,整理出简单好
千家信息网最后更新 2026年11月02日.Net Core怎么配置Configuration

这篇文章主要介绍".Net Core怎么配置Configuration",在日常操作中,相信很多人在.Net Core怎么配置Configuration问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答".Net Core怎么配置Configuration"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

目录
  • 核心类

  • 构建

    • ConfigurationBuilder

    • IConfigurationSource

    • ConfigurationProvider

    • ConfigurationRoot

  • 查询

    • 索引器

    • GetSection

  • DBConfiguration示例

    最近又研究了一下.NetCore配置选项的源码实现,又学习到了不少东西。这篇文章先写一下IConfiguration的学习成果,Options的后面补上

    核心类

    • ConfigurationBuilder:IConfigurationBuilder (构建IConfiguration)

    • IConfigurationSource (配置数据来源)

    • IConfigurationProvider (将配置源的原始结构转为为IDictionary)

    • ConfigurationRoot:IConfigurationRoot:IConfiguration (配置根节点)

    构建

    ConfigurationBuilder

    下面是ConfigurationBuilder中的主要代码

    可以看到ConfigurationBuilder的主要功能就是配置数据源到集合中

    在Build时依次调用IConfigurationSource的Build函数,并将返回的IConfigurationProvider加入到List中

    最后用IConfigurationProvider的集合构建一个ConfigurationRoot对象

    public IList Sources = new List();public IConfigurationBuilder Add(IConfigurationSource source){    Sources.Add(source);    return this;}public IConfigurationRoot Build(){    List list = new List();    foreach (IConfigurationSource source in Sources)    {        IConfigurationProvider item = source.Build(this);        list.Add(item);    }    return new ConfigurationRoot(list);}

    IConfigurationSource

    public class EnvironmentVariablesConfigurationSource : IConfigurationSource{    public string Prefix;    public IConfigurationProvider Build(IConfigurationBuilder builder)    {        return new EnvironmentVariablesConfigurationProvider(Prefix);    }    public EnvironmentVariablesConfigurationSource()    {    }}       public class CommandLineConfigurationSource : IConfigurationSource{    public IDictionary SwitchMappings;    public IEnumerable Args;    public IConfigurationProvider Build(IConfigurationBuilder builder)    {        return new CommandLineConfigurationProvider(Args, SwitchMappings);    }    public CommandLineConfigurationSource()    {    }}//JsonConfigurationSource继承自FileConfigurationSource,我这里将其合为一个了public abstract class JsonConfigurationSource : IConfigurationSource{ public IFileProvider FileProvider { get; set; } public string Path { get; set; } public bool Optional { get; set; } public bool ReloadOnChange { get; set; } public int ReloadDelay { get; set; } = 250; public Action OnLoadException { get; set; }     public IConfigurationProvider Build(IConfigurationBuilder builder) {  FileProvider = FileProvider ?? builder.GetFileProvider();  OnLoadException = OnLoadException ?? builder.GetFileLoadExceptionHandler();  return new JsonConfigurationProvider(this); }     public void ResolveFileProvider() {  if (FileProvider == null && !string.IsNullOrEmpty(Path) && System.IO.Path.IsPathRooted(Path))  {   string directoryName = System.IO.Path.GetDirectoryName(Path);   string text = System.IO.Path.GetFileName(Path);   while (!string.IsNullOrEmpty(directoryName) && !Directory.Exists(directoryName))   {    text = System.IO.Path.Combine(System.IO.Path.GetFileName(directoryName), text);    directoryName = System.IO.Path.GetDirectoryName(directoryName);   }   if (Directory.Exists(directoryName))   {    FileProvider = new PhysicalFileProvider(directoryName);    Path = text;   }  } }}

    上面展示了比较常用的三种ConfigurationSource,代码都比较简单。

    也很容易看出来ConfigurationSource的作用就是配置数据源,并不解析数据。

    解析数据源的功能由 IConfigurationProvider完成

    ConfigurationProvider

    下面为IConfigurationProvider接口定义的5个函数

    public interface IConfigurationProvider{ bool TryGet(string key, out string value); void Set(string key, string value); IChangeToken GetReloadToken(); void Load(); IEnumerable GetChildKeys(IEnumerable earlierKeys, string parentPath);}

    ConfigurationProvider是一个抽象类,继承了IConfigurationProvider接口

    在新建Provider时一般都会选择直接继承ConfigurationProvider,接下来看一下ConfigurationProvider的几个核心方法

    public abstract class ConfigurationProvider : IConfigurationProvider{ private ConfigurationReloadToken _reloadToken = new ConfigurationReloadToken();     protected IDictionary Data= new Dictionary(StringComparer.OrdinalIgnoreCase); public virtual bool TryGet(string key, out string value)=>Data.TryGetValue(key, out value); public virtual void Set(string key, string value)=>Data[key] = value; public virtual void Load(){} public IChangeToken GetReloadToken() {  return _reloadToken; }  protected void OnReload() { ConfigurationReloadToken configurationReloadToken = Interlocked.Exchange(ref _reloadToken, new ConfigurationReloadToken());  configurationReloadToken.OnReload(); }

    可以推测出:

    • Load函数负责从源数据读取数据然后给字典Data赋值

    • ConfigurationProvider将数据存储在字典Data中,增加修改都是对字典的操作

    • 每个ConfigurationProvider都会生成一个IChangeToken,在OnReload函数被调用时生成新的Token,并调用原Token的OnReload函数

    ConfigurationRoot

    在ConfigurationBuilder的Build函数中,我们生成了一个ConfigurationRoot,并给他传递了所有的ConfigrationProvider列表,下面我们看看他用我们的Provider都做了啥吧

    private ConfigurationReloadToken _changeToken = new ConfigurationReloadToken();public ConfigurationRoot(IList providers){    _providers = providers;    _changeTokenRegistrations = new List(providers.Count);    foreach (IConfigurationProvider p in providers)    {        p.Load();        ChangeToken.OnChange(p.GetReloadToken,            delegate{     var oldToken=Interlocked.Exchange(ref _changeToken, new ConfigurationReloadToken());                 oldToken.OnReload();                })    }}public IChangeToken GetReloadToken()=>_changeToken;

    上面的代码也对部分地方进行了简化。可以看到ConfigurationRoot在生成时主要就做了两件事

    • 1.调用Provider的Load函数,这会给Provider的Data赋值

    • 2.读取Provider的ReloadToken,每个Provider的Reload事件都会触发ConfigurationRoot自己的ReloadToken的Reload事件

    至此配置的数据源构建这块就分析完啦!

    查询

    常规的配置查询有两种基本方式 :索引器和GetSection(string key)

    其余的GetValue等等都是一些扩展方法,本篇文章不对此进行展开研究

    索引器

    索引器的查询执行的方式是倒叙查询所有的Provider,然后调用Provider的TryGet函数,在查询时重名的Key,最后加入的会生效。

    赋值则是依次调用每个Provider的Set函数

    public string this[string key]{ get {  for (int num = _providers.Count - 1; num >= 0; num--)  {   if (_providers[num].TryGet(key, out var value))   {    return value;   }  }  return null; } set {  foreach (IConfigurationProvider provider in _providers)  {   provider.Set(key, value);  } }}

    GetSection

    public IConfigurationSection GetSection(string key){ return new ConfigurationSection(this, key);}public class ConfigurationSection : IConfigurationSection, IConfiguration{ private readonly IConfigurationRoot _root; private readonly string _path; private string _key; public string Value {  get  {   return _root[Path];  }  set  {   _root[Path] = value;  } }     //ConfigurationPath.Combine = string.Join(":",paramList); public string this[string key] {  get  {   return _root[ConfigurationPath.Combine(Path, key)];  }  set  {   _root[ConfigurationPath.Combine(Path, key)] = value;  } } public ConfigurationSection(IConfigurationRoot root, string path) {  _root = root;  _path = path; } public IConfigurationSection GetSection(string key) {  return _root.GetSection(ConfigurationPath.Combine(Path, key)); } public IEnumerable GetChildren() {  return _root.GetChildrenImplementation(Path); } public IChangeToken GetReloadToken() {  return _root.GetReloadToken(); }}

    可以看到GetSection会生成一个ConfigurationSection对象

    而ConfigurationSection在读取/设置值时实际上就是对查询的Key用:拼接,然后调用IConfigurationRoot(_root)的赋值或查询函数

    关于Configuration的配置和读取的知识点大概就是以上这些了,还有更深入的涉及到对象的绑定这一块Get<> Bind<> GetChildren()等,比较难读,要一行一行代码看,以后有时间可能再研究一下

    最后贴上一个从数据加载配置源并动态更新的小例子

    DBConfiguration示例

     public void Run() {     var builder = new ConfigurationBuilder();     var dataProvider = new DBDataProvider();     builder.Sources.Add(new DBConfigurationSource() { DataProvider = dataProvider, ReloadOnChange = true, Table = "config" });     IConfigurationRoot config = builder.Build();     Console.WriteLine(config["time"]);     Task.Run(() =>              {                  while (true)                  {                      Thread.Sleep(2000);                      dataProvider.Update("config");                      Console.WriteLine($"读取配置时间:{config["time"]}");                  }              });     Thread.Sleep(20000); }public class DBConfigurationProvider : ConfigurationProvider{    private DBConfigurationSource Source { get; }    public DBConfigurationProvider(DBConfigurationSource source)    {        Source = source;    }    public override void Load()    {        if (Source.ReloadOnChange)        {            ChangeToken.OnChange(() => Source.DataProvider.Watch(Source.Table), LoadData);        }        LoadData();    }    private void LoadData()    {        var data = Source.DataProvider.GetData(Source.Table);        Load(data);        OnReload();    }    public void Load(Dictionary data)    {        var dic = new SortedDictionary(StringComparer.OrdinalIgnoreCase);        foreach (var element in data)        {            dic.Add(element.Key, element.Value?.ToString());        }        base.Data = dic;    }}public class DBConfigurationSource : IConfigurationSource{    public DBDataProvider DataProvider { get; set; }    public string Table { get; set; }    public bool ReloadOnChange { get; set; }    public bool Optional { get; set; }    public DBConfigurationSource()    {    }    public IConfigurationProvider Build(IConfigurationBuilder builder)    {        return new DBConfigurationProvider(this);    }}public class DBDataProvider{    private ConcurrentDictionary tableToken = new ConcurrentDictionary();    public DBDataProvider()    {    }    public Dictionary GetData(string table)    {        switch (table)        {            case "config":                return GetConfig();        }        return new Dictionary();    }    public void Update(string table)    {        Console.WriteLine($"更新数据库数据table:{table}");        if (tableToken.TryGetValue(table, out CancellationTokenSource cts))        {            var oldCts = cts;            tableToken[table] = new CancellationTokenSource();            oldCts.Cancel();        }    }    private Dictionary GetConfig()    {        var valueDic = new Dictionary();        valueDic.TryAdd("time", DateTime.Now.ToString());        valueDic.TryAdd("weather", "windy");        valueDic.TryAdd("people_number:male", 100);        valueDic.TryAdd("people_number:female", 150);        return valueDic;    }    public IChangeToken Watch(string table)    {        var cts = tableToken.GetOrAdd(table, x => new CancellationTokenSource());        return new CancellationChangeToken(cts.Token);    }}

    到此,关于".Net Core怎么配置Configuration"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

    配置 数据 函数 查询 学习 生成 代码 就是 数据源 索引 字典 对象 方法 核心 研究 一行 事件 功能 接口 文章 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网黑科技 上海睿民互联网科技有限公司 华服互联网科技怎么样 湖南永感互联网科技有限公司 互联网公司 科技公司 互联网金融 科技 腾讯科技 互联网女皇 人人互联网科技是培训 四个字互联网科技公司取名 中正互联网科技招聘 互联网科技公司招聘 天速互联网络科技有限公司 济南华为互联网科技产业总部基地 银川新华互联网科技职业技术培训学校图片 恒生互联网科技指数跳水 互联网科技大奖都有哪些公司 亳州好赞互联网科技有限公司 迪庆互联网科技招生 互联网科技创新的路径 广州梦谷互联网科技有限公司领导 鸠鸠互联网科技 西安互联网科技 互联网科技媒体 山东吉时兔互联网科技有限公司 北京大学互联网科技怎么样 爱医互联网络科技 互联网企业科技类企业如何做账 银行科技岗属于互联网吗 上海万顺科技互联网有限公司招聘 易租星互联网科技有限公司
    0