最近在學習.Net Core的過程中,發現.Net Framework中常用的ConfigurationManager在Core中竟然被干掉了。
也能理解。Core中使用的配置文件全是Json,不像Framework使用的XML,暫時不支持也是能理解的,但是畢竟全局配置文件這種東西還挺重要的,閱讀了一些文章后目前有3個解決方案。
一、引入擴展System.Configuration.ConfigurationManager
這個擴展庫可以直接在Nuget中獲取。
使用方法和說明見.NET Core 2.0遷移技巧之web.config配置文件
讀取的文件類型和方法都跟.Net Framework中一致,而且僅需引入包就可以,瞬間很興奮有木有!
但是!在使用過過程中發現這個擴展有問題。項目運行過程中需修改我的app.config文件,對我項目中輸出的內容沒有絲毫影響,Debug發現獲取到的值的確沒有變化。重啟項目都沒有用。只有把項目重新編譯才好使。
不知道是不是因為我的打開方式不對,但是最終放棄這個方法。
二、引入擴展Microsoft.Extensions.Options.ConfigurationExtensions
這個擴展庫也可以直接在Nuget中獲取。
使用方法和說明見 ASP.NET Core實現類庫項目讀取配置文件
這個可以讀取application.json中的配置參數,不再使用XML可以說很好的貼近Core的設計理念。
可惜,這個也有點美中不足的地方。首先跟上面的那個一樣,運行時修改json文件讀取到的內容不會改變,但是至少重啟項目可以修改,這個讓我欣慰很多。另外就是,這個方法采用的是反序列化的原理,也就是必須有一個跟配置文件對應的實體類才可以,這個感覺比較雞肋,放棄。
三、自定義擴展方法
這個是我這次說的重點,要是前面兩個方法能滿足讀者你的需求,那么就沒有必要看下去。
廢話少說,先上代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
|
public class ConfigurationManager { /// <summary> /// 配置內容 /// </summary> private static NameValueCollection _configurationCollection = new NameValueCollection(); /// <summary> /// 配置監聽響應鏈堆棧 /// </summary> private static Stack<KeyValuePair< string , FileSystemWatcher>> FileListeners = new Stack<KeyValuePair< string , FileSystemWatcher>>(); /// <summary> /// 默認路徑 /// </summary> private static string _defaultPath = Directory.GetCurrentDirectory() + "\\appsettings.json" ; /// <summary> /// 最終配置文件路徑 /// </summary> private static string _configPath = null ; /// <summary> /// 配置節點關鍵字 /// </summary> private static string _configSection = "AppSettings" ; /// <summary> /// 配置外連接的后綴 /// </summary> private static string _configUrlPostfix = "Url" ; /// <summary> /// 最終修改時間戳 /// </summary> private static long _timeStamp = 0L; /// <summary> /// 配置外鏈關鍵詞,例如:AppSettings.Url /// </summary> private static string _configUrlSection { get { return _configSection + "." + _configUrlPostfix; } } static ConfigurationManager() { ConfigFinder(_defaultPath); } /// <summary> /// 確定配置文件路徑 /// </summary> private static void ConfigFinder( string Path) { _configPath = Path; JObject config_json = new JObject(); while (config_json != null ) { config_json = null ; FileInfo config_info = new FileInfo(_configPath); if (!config_info.Exists) break ; FileListeners.Push(CreateListener(config_info)); config_json = LoadJsonFile(_configPath); if (config_json[_configUrlSection] != null ) _configPath = config_json[_configUrlSection].ToString(); else break ; } if (config_json == null || config_json[_configSection] == null ) return ; LoadConfiguration(); } /// <summary> /// 讀取配置文件內容 /// </summary> private static void LoadConfiguration() { FileInfo config = new FileInfo(_configPath); var configColltion = new NameValueCollection(); JObject config_object = LoadJsonFile(_configPath); if (config_object == null || !(config_object is JObject)) return ; if (config_object[_configSection]!= null ) { foreach (JProperty prop in config_object[_configSection]) { configColltion[prop.Name] = prop.Value.ToString(); } } _configurationCollection = configColltion; } /// <summary> /// 解析Json文件 /// </summary> /// <param name="FilePath">文件路徑</param> /// <returns></returns> private static JObject LoadJsonFile( string FilePath) { JObject config_object = null ; try { StreamReader sr = new StreamReader(FilePath, Encoding.Default); config_object = JObject.Parse(sr.ReadToEnd()); sr.Close(); } catch { } return config_object; } /// <summary> /// 添加監聽樹節點 /// </summary> /// <param name="info"></param> /// <returns></returns> private static KeyValuePair< string , FileSystemWatcher> CreateListener(FileInfo info) { FileSystemWatcher watcher = new FileSystemWatcher(); watcher.BeginInit(); watcher.Path = info.DirectoryName; watcher.Filter = info.Name; watcher.IncludeSubdirectories = false ; watcher.EnableRaisingEvents = true ; watcher.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.CreationTime | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.Size; watcher.Changed += new FileSystemEventHandler(ConfigChangeListener); watcher.EndInit(); return new KeyValuePair< string , FileSystemWatcher>(info.FullName, watcher); } private static void ConfigChangeListener( object sender, FileSystemEventArgs e) { long time = TimeStamp(); lock (FileListeners) { if (time > _timeStamp) { _timeStamp = time; if (e.FullPath != _configPath || e.FullPath == _defaultPath) { while (FileListeners.Count > 0) { var listener = FileListeners.Pop(); listener.Value.Dispose(); if (listener.Key == e.FullPath) break ; } ConfigFinder(e.FullPath); } else { LoadConfiguration(); } } } } private static long TimeStamp() { return ( long )((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds * 100); } private static string c_configSection = null ; public static string ConfigSection { get { return _configSection; } set { c_configSection = value; } } private static string c_configUrlPostfix = null ; public static string ConfigUrlPostfix { get { return _configUrlPostfix; } set { c_configUrlPostfix = value; } } private static string c_defaultPath = null ; public static string DefaultPath { get { return _defaultPath; } set { c_defaultPath = value; } } public static NameValueCollection AppSettings { get { return _configurationCollection; } } /// <summary> /// 手動刷新配置,修改配置后,請手動調用此方法,以便更新配置參數 /// </summary> public static void RefreshConfiguration() { lock (FileListeners) { //修改配置 if (c_configSection != null ) { _configSection = c_configSection; c_configSection = null ; } if (c_configUrlPostfix != null ) { _configUrlPostfix = c_configUrlPostfix; c_configUrlPostfix = null ; } if (c_defaultPath != null ) { _defaultPath = c_defaultPath; c_defaultPath = null ; } //釋放掉全部監聽響應鏈 while (FileListeners.Count > 0) FileListeners.Pop().Value.Dispose(); ConfigFinder(_defaultPath); } } } |
最開始設計的是采用緩存,每次調用比對文件的修改時間,大小等特征,出現變化從新載入配置。后來發現圖樣圖森破!
C#提供了專門監聽文件系統的方法。所以從新設計了監聽響應鏈堆棧來實現。
使用說明:
1、配置節點:
可以直接寫在項目默認的配置文件appsettings.json中 格式如下
1
2
3
4
5
6
7
|
保證配置節點AppSettings存在,剩下的就是以Key-Value的形式來寫屬性,就可以。
2、外部配置文件
像.Net Framework中一樣,可以通過外部配置文件來實現。格式如下
1
2
3
|
{ "AppSettings.Url" : "D:\\test\\app1.json" } |
采用格式是“配置節點名.外鏈后綴”的形式。可以設計多級外部配置文件,只要發現有外部配置節點就會向下尋找,并監聽鏈上的所有節點文件的變化。
但是需要注意的是:一旦存在外部配置節點,此文件中的配置節點和參數將不再參與解析
3、可配置初始化參數
包括默認文件路徑在內的多個參數均可以修改,詳情見代碼。
修改后需要手動調用RefreshConfiguration方法,以使配置內容生效,有點像事務處理。建議在項目的Startup方法中修改配置方法。
4、使用
跟.Net Framework中一樣,直接調用ConfigurationManager.Appsettings["Title"]就可以了。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://www.cnblogs.com/kasimlz/p/7515810.html