.NET Core 讀取配置文件方式總結

基於.NET Core的跨平臺開發,配置文件與以前.NET Framework採用xml的config文件不一樣,目前主要是採用json文件鍵值對配置方式讀取。html

參考網上相關資料總結以下:json

1、引入擴展 System.Configuration.ConfigurationManager

Nuget 下載擴展,Install-Package System.Configuration.ConfigurationManagerapp

使用方式:添加配置文件App.config。讀取方式與原.NET Framework方式一致spa

優勢:兼容.NET Framework 原有配置方式設計

缺點:項目運行過程當中若需修改App.config文件,對項目中輸出的內容沒有絲毫影響,Debug發現獲取到的值的確沒有變化,須要從新編譯才生效。code

 

2、引入擴展 Microsoft.Extensions.Options.ConfigurationExtensions

Nuget 下載擴展, xml

Install-Package Microsoft.Extensions.Options.ConfigurationExtensions htm

Install-Package Microsoft.Extensions.Configuration.FileExtensionsblog

Install-Package Microsoft.Extensions.Configuration.Json開發

使用方式:參考微軟官網:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/configuration/index?view=aspnetcore-2.1&tabs=basicconfiguration

優勢:能夠讀取application.json中的配置參數,再也不使用XML能夠說很好的貼近Core的設計理念

缺點:運行時修改json文件讀取到的內容不會改變,可是至少重啓項目能夠修改,若要運行時候修改json文件監聽實現監聽變化。查看源碼,能夠發現 雖然配置信息是經過AddSingleton注入的
但同時也注入了IOptionsChangeTokenSource ,故只須要在獲取配置信息時將IOptions<> 替換爲 IOptionsMonitor<>(經過監聽的Option來獲取信息),並經過 IOptionsMonitor<>.CurrentValue獲取便可實時獲取到最新的配置信息(存在修改監聽)

另外就是,這個方法採用的是反序列化的原理,也就是必須有一個跟配置文件對應的實體類才能夠,這個感受比較雞肋,放棄。

3、自定義擴展方法,這個實現本身寫,原理是監聽文件是否變動,來刷新Configuration 配置實現。

參考園友一個實現,具體須要是否有效,要花時間實踐一下,原連接地址:http://www.cnblogs.com/kasimlz/p/7515810.html,代碼以下:

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);
            }
        }

    }
相關文章
相關標籤/搜索