????????ConfigurationProvider
?????????????????????????ConfigurationProvider????????????IConfigurationProvider???????????????????????????????????????????????ConfigurationProvider??????????????????????????????????????????????????????????????????????????????????????????IConfigurationProvider????е?????????????????????????????
????1: public interface IConfigurationProvider
????2: {
????3:    void Load();
????4:
????5:    bool TryGet(string key?? out string value);
????6:    void Set(string key?? string value);
????7:    IEnumerable<string> GetChildKeys(IEnumerable<string> earlierKeys?? string parentPath?? string delimiter)
????8: }
???????????????????????ConfigurationProvider??Load????????ɡ???????????TryGet??????????????Key????????????????????????????????????ConfigurationProvider???????????????????ConfigurationProvider?????????????ж?????????????????????±????????????????????????????????Set???????????????????????????????С?ConfigurationProvider??GetChildKeys?????????????·????????y???????????Key??
????????????????????????ж????ConfigurationProvider?????????????????????????IConfigurationProvider??????????????????ConfigurationProvider?????????????????????????????????μ??????ο??????????????????IDictionary<string?? string>???????????Set??TryGetValue??????????????????????????????Load??????????????鷽?????????ConfigurationProvider?????????д????????????????????ж????????????????????????г??????
1: public abstract class ConfigurationProvider : IConfigurationProvider
2: {
3:     protected IDictionary<string?? string> Data { get; set; }
4:
5:     public IEnumerable<string> GetChildKeys(IEnumerable<string> earlierKeys?? string parentPath?? string delimiter)
6:     {
7:         //??????
8:     }
9:
10:     public virtual void Load()
11:     {}
12:
13:     public void Set(string key?? string value)
14:     {
15:         this.Data[key] = value;
16:     }
17:
18:     public bool TryGet(string key?? out string value)
19:     {
20:         return this.Data.TryGetValue(key?? out value);
21:     }
22:     //???????
23: }
??????????????????????????????????????GetChildKeys??????????????????·????Key????????????????????????λ???ν??????????????????????????y?????????????????y??Key???????????y????????parentPath?????·??????????????????delimiter????·????????????????????????????????????????????????????earlierKeys???????????????????Key??????б??????????????С?
1: class Program
2: {
3:     static void Main(string[] args)
4:     {
5:         Dictionary<string?? string> source = new Dictionary<string?? string>
6:         {
7:             ["A:B:C"]     = ""??
8:             ["A:B:D"]     = ""??
9:             ["A:E"]         = ""??
10:         };
11:
12:         MemoryConfigurationProvider provider = new MemoryConfigurationProvider(source);
13:         Console.WriteLine("{0?? -20}{1}"?? "Parent Path"?? "Child Keys");
14:         Console.WriteLine("------------------------------------------");
15:
16:         Print("Null"?? provider.GetChildKeys(new string[] { "X"?? "Y"?? "Z" }?? null?? ":"));
17:         Print("A"?? provider.GetChildKeys(new string[] { "x"?? "y"?? "z" }?? "A"?? ":"));
18:         Print("A:B"?? provider.GetChildKeys(new string[] { "X"?? "Y"?? "Z }?? "A:B"?? ":"));
19:         Print("A:B:C"??provider.GetChildKeys(new string[] { "X"?? "Y"?? "Z }?? "A:B:C"?? ":"));
20:     }
21:
22:     static void Print(string parentPath?? IEnumerable<string> keys)
23:     {
24:         Console.WriteLine("{0?? -20}{1}"?? parentPath?? string.Join("?? "?? keys.ToArray()));
25:     }
26: }
????????????????????????????????GetChildKeys????????????????д????????????????????????????MemoryConfigurationProvider???????????????????????????????????????????Key?????“A??B??C”??“A??B??D”??“A??E”?????????????GetChildKeys?????????????????·?????????“A”??“A??B??“A??B??C”????????????Key????????????????e???“??”???????????????earlierKeys????????“X”??“Y”??“Z”???????????顣??γ????????????????????????μ???????????????п???????????????????????н??????Key?????
????1: Parent Path         Child Keys
????2: ------------------------------------------
????3: Null                X?? Y?? Z
????4: A                   B?? B?? E?? X?? Y?? Z:
????5: A:B                 C?? D?? X?? Y?? Z
????6: A:B:C               X?? Y?? Z
???????ConfigurationBuilder
????ConfigurationBuilder????????????IConfigurationBuilder??????????????????????????е???????????????ConfigurationProvider??????????????????????????????????Configuration??????????????????????????????????ConfigurationRoot???????ConfigurationBuilder???ConfigurationProvider?????IConfigurationBuilder????Providers???????????????Add??????ConfigurationProvider????????????С?
????1: public interface IConfigurationBuilder
????2: {
????3:     IEnumerable<IConfigurationProvider>     Providers { get; }
????4:     Dictionary<string?? object>         Properties { get; }
????5:
????6:     IConfigurationBuilder Add(IConfigurationProvider provider);
????7:     IConfigurationRoot Build();
????8: }
???????????IConfigurationBuilder????????????????????????Properties???????????????????????????????ConfigurationBuilder?????????????????Key?????Щ???????ConfigurationRoot??????????Build??????ɡ?
????????????????????????????IConfigurationBuilder??????????????????????????????ж??????ConfigurationBuilder????????????????????????????????????Build?????С???????????????ConfigurationBuilder???е?Build????????????????????ConfigurationRoot??????????????????ConfigurationSection????????????y??????????UML???????????????Configuration??ConfigurationProvider??ConfigurationBuilder???????????/???????????????????

????ConfigurationRoot??ConfigurationSection????????????????????????????????????????????????????????????????????????????????????????????????????????Configuration??????????????????ConfigurationRoot????ConfigurationSection???????????????з???κε????????????????????????????????д??????????????????ConfigurationProvider???????Configuration????????????ConfigurationProvider????????????????ConfigurationBuilder??????????ConfigurationRoot???????Ч???????????????????????????Ч???
????1: IConfigurationBuilder builder = new ConfigurationBuilder().Add(new MemoryConfigurationProvider());
????2:
????3: IConfiguration config1 = builder.Build();
????4: IConfiguration config2 = builder.Build();
????5:
????6: config1["Foobar"] = "ABC";
????7: Debug.Assert(config2["Foobar"] == "ABC");
????xxx???????????ConfigurationRoot??ConfigurationSection????????????????????????y?????????????????????????????????ù?????????????????????????????????????????????y??ConfigurationSection??????????????????????????????????????????????ConfigurationRoot??????????????ConfigurationSection?????????????????????????????????????????????????????????????ConfigurationRoot????

????????????????????????????ConfigurationSection????????????y?????????????????????????????????????????????????????ConfigurationRoot?????????????·???????????????ConfigurationRoot??????ConfigurationProvider?????????·?????????????????????????????????????

????????????ConfigurationRoot??ConfigurationSection???????????????????д??????????????????????????????????????????????????????????????????????????????????ConfigurationPath?????????????壬ConfigurationPath????????????????????·?????????????Combine???????????κ?????????????·????GetSectionKey??????????????·??????????Key????GetParentPath??????????·????????????·????
????1: public static class ConfigurationPath
????2: {
????3:     public static string Combine(params string[] pathSegements) ;
????4:     public static string Combine(IEnumerable<string> pathSegements) ;
????5:     public static string GetSectionKey(string path) ;
????6:     public static string GetParentPath(string path) ;
????7: }
????ConfigurationRoot
????ConfigurationRoot???????????????????????????????????????С????ConfigurationRoot?????????????????????????ConfigurationProvider???????ζ???????????д???????????????????????????????????????????Key??????????????????????????ConfigurationProvider????????????????????????Key??????????ε??????ConfigurationProvider??TryGet????????÷???????True????????????????????????????????????????????????????????????????????????????????????ConfigurationProvider??Set??????
1: public class ConfigurationRoot: IConfigurationRoot
2: {
3:     private IList<IConfigurationProvider> providers;
4:
5:     public ConfigurationRoot(IList<IConfigurationProvider> providers)
6:     {
7:         this.providers = providers;
8:         providers.ForEach(provider => provider.Load());
9:     }
10:
11:     public string this[string key]
12:     {
13:         get
14:         {
15:             string value = null;
16:             return providers.Reverse().Any(p => p.TryGet(key?? out value))
17:                 ? value: null;
18:         }
19:         set
20:         {
21:             providers.ForEach(provider => provider.Set(key?? value));
22:         }
23:     }
24:
25:     public IEnumerable<IConfigurationSection> GetChildren()=> this.GetChildren(null);
26:
27:     public IConfigurationSection GetSection(string key) => new ConfigurationSection(this?? key);
28:
29:     public void Reload() => providers.ForEach(provider => provider.Load());
30:
31:     internal IEnumerable<IConfigurationSection> GetChildrenCore(string path)
32:     {
33:         return providers.Aggregate(Enumerable.Empty<string>()??
34:             (seed?? source) => source.GetChildKeys(seed?? path?? ":"))
35:             .Distinct()
36:             .Select(key => GetSection(ConfigurationPath.Combine(path?? key)));
37:     }
38:     //???????
39: }
????ConfigurationRoot??????????ж???????????????????????????????????????????????????????????ж????????????????ConfigurationBuilder?е?ConfigurationProvider???и????????????????????????????ConfigurationProvider“????????”?????????????????????е????????????????????????????ConfigurationProvider????ConfigurationBuilder?????ɡ?
????????????????????????GetChildrenCore???????????y???????????y?????????????y?????????????·????????????????????????????ConfigurationProvider??GetChildKeys???????????????????????y??Key???????????????????????y??ConfigurationSection??????????GetChildren?????У?????????????????????????????????????????y?????????GetSection?????У?????????????????·???????????????y??????????key??????y??·??????????ConfigurationSection????
????ConfigurationSection
????????????????????ConfigurationRoot??????????????????????????????y??ConfigurationSection?????????????·????????????y??ConfigurationRoot?????????ConfigurationRoot????????д??????????????ConfigurationProvider????????ConfigurationSection??????????????y???????д??????????????????????????????????????С?
1: public class ConfigurationSection: IConfigurationSection
2: {
3:     private ConfigurationRoot root;
4:     private string key;
5:
6:     public string Key
7:     {
8:         get { return key ?? (key = ConfigurationPath.GetSectionKey(this.Path)); }
9:     }
10:     public string Path { get; private set; }
11:     public string Value { get;  set; }
12:     public string this[string key]
13:     {
14:         get
15:         {
16:             return root[this.Path];
17:         }
18:
19:         set
20:         {
21:             root[this.Path] = Value;
22:         }
23:     }
24:
25:     public ConfigurationSection(ConfigurationRoot root?? string path)
26:     {
27:         this.root = root;
28:         this.Path = path;
29:     }
30:
31:     public IConfigurationSection GetSection(string key) => root.GetSection(ConfigurationPath.Combine(this.Path?? key));
32:     public IEnumerable<IConfigurationSection> GetChildren() => root.GetChildren(this.Path);
33:     //???????
34: }
????[1] ForEach???????????????????????IEnumerable<T>???????????????????????????????????????