看下Provider:
/// <summary> /// Provides configuration key/values for an application. /// </summary> public interface IConfigurationProvider { /// <summary> /// Tries to get a configuration value for the specified key. /// </summary> /// <param>The key.</param> /// <param>The value.</param> /// <returns><c>True</c> if a value for the specified key was found, otherwise <c>false</c>.</returns> bool TryGet(string key, out string value); /// <summary> /// Sets a configuration value for the specified key. /// </summary> /// <param>The key.</param> /// <param>The value.</param> void Set(string key, string value); /// <summary> /// Returns a change token if this provider supports change tracking, null otherwise. /// </summary> /// <returns>The change token.</returns> IChangeToken GetReloadToken(); /// <summary> /// Loads configuration values from the source represented by this <see cref="IConfigurationProvider"/>. /// </summary> void Load(); /// <summary> /// Returns the immediate descendant configuration keys for a given parent path based on this /// <see cref="IConfigurationProvider"/>s data and the set of keys returned by all the preceding /// <see cref="IConfigurationProvider"/>s. /// </summary> /// <param>The child keys returned by the preceding providers for the same parent path.</param> /// <param>The parent path.</param> /// <returns>The child keys.</returns> IEnumerable<string> GetChildKeys(IEnumerable<string> earlierKeys, string parentPath); }查看头部:
/// <summary> /// Provides configuration key/values for an application. /// </summary> public interface IConfigurationProvider为应用提供key value配置。
那么这时候猜想ConfigurationRoot就是来整合配置的。
先看我们上文一组IConfigurationSource,IConfigurationProvider的具体实现MemoryConfigurationSource 和 MemoryConfigurationProvider。
MemoryConfigurationSource :
MemoryConfigurationProvider:
/// <summary> /// In-memory implementation of <see cref="IConfigurationProvider"/> /// </summary> public class MemoryConfigurationProvider : ConfigurationProvider, IEnumerable<KeyValuePair<string, string>> { private readonly MemoryConfigurationSource _source; /// <summary> /// Initialize a new instance from the source. /// </summary> /// <param>The source settings.</param> public MemoryConfigurationProvider(MemoryConfigurationSource source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } _source = source; if (_source.InitialData != null) { foreach (KeyValuePair<string, string> pair in _source.InitialData) { Data.Add(pair.Key, pair.Value); } } } /// <summary> /// Add a new key and value pair. /// </summary> /// <param>The configuration key.</param> /// <param>The configuration value.</param> public void Add(string key, string value) { Data.Add(key, value); } /// <summary> /// Returns an enumerator that iterates through the collection. /// </summary> /// <returns>An enumerator that can be used to iterate through the collection.</returns> public IEnumerator<KeyValuePair<string, string>> GetEnumerator() { return Data.GetEnumerator(); } /// <summary> /// Returns an enumerator that iterates through the collection. /// </summary> /// <returns>An enumerator that can be used to iterate through the collection.</returns> IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } }所以我们如果要扩展的来源的话,需要实现IConfigurationSource、IConfigurationProvider即可。
那么有时候我们会在配置文件中看到:
{ "section1:key3":"value3" }是否这个解释含义是section1:key3作为key然后value3作为value呢?
其实不是,这是为了能够让配置分组。
static void Main(string[] args) { IConfigurationBuilder builder = new ConfigurationBuilder(); builder.AddInMemoryCollection(new Dictionary<string,string>() { {"key1","value1"}, {"key2","value2"}, {"section1:key3","values3"} }); IConfigurationRoot configurationRoot = builder.Build(); Console.WriteLine(configurationRoot["key1"]); Console.WriteLine(configurationRoot["key2"]); Console.WriteLine(configurationRoot["section1:key3"]); Console.WriteLine(configurationRoot.GetSection("section1")["key3"]); }