1
1
using Newtonsoft . Json ;
2
+ using Newtonsoft . Json . Linq ;
2
3
using PropertyChanged ;
3
4
using System ;
5
+ using System . Collections . Concurrent ;
4
6
using System . Collections . Generic ;
5
7
using System . IO ;
6
8
using System . Linq ;
@@ -16,22 +18,33 @@ public class SettingsProvider : ServiceProviderBase
16
18
{
17
19
private string configPath { get => Path . Combine ( AppDomain . CurrentDomain . BaseDirectory , "config" ) ; }
18
20
private string settingsPath { get => Path . Combine ( configPath , "settings.json" ) ; }
19
- private List < SettingsBase > Settings { get ; set ; } = new List < SettingsBase > ( ) ;
21
+ private ConcurrentDictionary < string , SettingsBase > Settings { get ; set ; } = new ConcurrentDictionary < string , SettingsBase > ( ) ;
20
22
21
23
public SettingsProvider ( )
22
24
{
25
+ bool initialConfig = false ;
23
26
if ( ! Directory . Exists ( this . configPath ) )
24
27
{
25
28
Directory . CreateDirectory ( this . configPath ) ;
26
29
}
27
30
if ( ! File . Exists ( this . settingsPath ) )
28
31
{
32
+ initialConfig = true ;
29
33
initializeConfig ( ) ;
30
34
}
31
- this . Settings . AddRange (
32
- Assembly . GetEntryAssembly ( ) . GetTypes ( )
35
+ Assembly . GetEntryAssembly ( ) . GetTypes ( )
33
36
. Where ( x => x . GetCustomAttributes < SettingsSectionAttribute > ( ) . Count ( ) > 0 )
34
- . Select ( x => Activator . CreateInstance ( x ) as SettingsBase ) ) ;
37
+ . Select ( x => Activator . CreateInstance ( x ) as SettingsBase ) . ToList ( ) . ForEach ( x =>
38
+ {
39
+ this . Settings . AddOrUpdate (
40
+ x . GetType ( ) . GetCustomAttribute < SettingsSectionAttribute > ( ) ? . name ,
41
+ key => x ,
42
+ ( key , oldSettings ) => oldSettings = x ) ;
43
+ } ) ;
44
+ if ( ! initialConfig )
45
+ {
46
+ this . LoadSettings ( ) . Wait ( ) ;
47
+ }
35
48
36
49
}
37
50
private void initializeConfig ( )
@@ -50,12 +63,52 @@ private void initializeConfig()
50
63
}
51
64
public T GetConfig < T > ( ) where T : SettingsBase
52
65
{
53
- return this . Settings . FirstOrDefault ( x => x . GetType ( ) == typeof ( T ) ) as T ;
66
+ return this . Settings . FirstOrDefault ( x => x . Value . GetType ( ) == typeof ( T ) ) . Value as T ;
67
+ }
68
+ public void UpdateConfig < T > ( T settings , bool saveToFile = false ) where T : SettingsBase
69
+ {
70
+ this . Settings . AddOrUpdate (
71
+ settings . GetType ( ) . GetCustomAttribute < SettingsSectionAttribute > ( ) ? . name ,
72
+ key => settings ,
73
+ ( key , oldSettings ) => oldSettings = settings ) ;
74
+ if ( saveToFile )
75
+ {
76
+ this . SaveSettings ( ) ;
77
+ }
54
78
}
55
- public void UpdateConfig < T > ( T settings ) where T : SettingsBase
79
+ public async Task LoadSettings ( )
56
80
{
57
- var itemIndex = this . Settings . FindIndex ( x => x . GetType ( ) == typeof ( T ) ) ;
58
- this . Settings [ itemIndex ] = settings ;
81
+ var settingsIn = File . ReadAllText ( this . settingsPath ) ;
82
+ var settings = JsonConvert . DeserializeObject < Dictionary < string , object > > ( settingsIn ) ;
83
+
84
+ var availableSettings = Assembly . GetEntryAssembly ( ) . GetTypes ( )
85
+ . Where ( x => x . GetCustomAttributes < SettingsSectionAttribute > ( ) . Count ( ) > 0 ) ;
86
+ settings . ToList ( ) . ForEach ( x =>
87
+ {
88
+ if ( this . Settings . ContainsKey ( x . Key ) )
89
+ {
90
+ var avSetting = availableSettings . FirstOrDefault ( y => y . GetCustomAttribute < SettingsSectionAttribute > ( ) ? . name == x . Key ) ;
91
+ if ( avSetting != null )
92
+ {
93
+ var obj = ( x . Value as JObject ) . ToObject ( avSetting ) ;
94
+ this . Settings . AddOrUpdate ( x . Key , key => obj as SettingsBase , ( key , oldSetting ) => oldSetting = obj as SettingsBase ) ;
95
+ }
96
+ }
97
+ } ) ;
98
+ }
99
+ public async Task SaveSettings ( )
100
+ {
101
+ try
102
+ {
103
+ File . WriteAllText ( this . settingsPath , JsonConvert . SerializeObject ( this . Settings , Formatting . Indented ) ) ;
104
+ }
105
+ catch ( Exception ex )
106
+ {
107
+ if ( ! ( ex is FileNotFoundException || ex is DirectoryNotFoundException ) )
108
+ {
109
+ throw ex ;
110
+ }
111
+ }
59
112
}
60
113
}
61
114
public abstract class SettingsBase { }
0 commit comments