1+ using System . Collections . Generic ;
2+ using System . IO ;
3+ using System . Linq ;
4+ using System . Threading . Tasks ;
5+ using Microsoft . Extensions . Configuration ;
6+ using Oakton . Descriptions ;
7+ using Spectre . Console ;
8+
9+ namespace OaktonDescribe
10+ {
11+ public class ConfigDescriptionSystemPart : IDescribedSystemPart , IWriteToConsole
12+ {
13+ readonly IConfigurationRoot _configRoot ;
14+
15+ public ConfigDescriptionSystemPart ( IConfiguration config )
16+ {
17+ _configRoot = config as IConfigurationRoot ;
18+ }
19+
20+ public string Title => "Configuration values and sources" ;
21+
22+ public Task Write ( TextWriter writer )
23+ {
24+ return writer . WriteAsync ( _configRoot . GetDebugView ( ) ) ;
25+ }
26+
27+ public Task WriteToConsole ( )
28+ {
29+ void RecurseChildren ( IHasTreeNodes node , IEnumerable < IConfigurationSection > children )
30+ {
31+ foreach ( IConfigurationSection child in children )
32+ {
33+ ( string Value , IConfigurationProvider Provider ) valueAndProvider = GetValueAndProvider ( _configRoot , child . Path ) ;
34+
35+ IHasTreeNodes parent = node ;
36+ if ( valueAndProvider . Provider != null )
37+ {
38+ node . AddNode ( new Table ( )
39+ . Border ( TableBorder . None )
40+ . HideHeaders ( )
41+ . AddColumn ( "Key" )
42+ . AddColumn ( "Value" )
43+ . AddColumn ( "Provider" )
44+ . HideHeaders ( )
45+ . AddRow ( $ "[yellow]{ child . Key } [/]", valueAndProvider . Value , $@ "([grey]{ valueAndProvider . Provider } [/])")
46+ ) ;
47+ }
48+ else
49+ {
50+ parent = node . AddNode ( $ "[yellow]{ child . Key } [/]") ;
51+ }
52+
53+ RecurseChildren ( parent , child . GetChildren ( ) ) ;
54+ }
55+ }
56+
57+ var tree = new Tree ( string . Empty ) ;
58+
59+ RecurseChildren ( tree , _configRoot . GetChildren ( ) ) ;
60+
61+ AnsiConsole . Render ( tree ) ;
62+
63+ return Task . CompletedTask ;
64+ }
65+
66+ private static ( string Value , IConfigurationProvider Provider ) GetValueAndProvider (
67+ IConfigurationRoot root ,
68+ string key )
69+ {
70+ foreach ( IConfigurationProvider provider in root . Providers . Reverse ( ) )
71+ {
72+ if ( provider . TryGet ( key , out string value ) )
73+ {
74+ return ( value , provider ) ;
75+ }
76+ }
77+
78+ return ( null , null ) ;
79+ }
80+ }
81+ }
0 commit comments