第一部分、基于鍵值對的配置如果要使用結(jié)構(gòu)化配置,需要先引用 "Microsoft.Extensions.Configuration": "1.0.0" nuget包。下面通過一個.Net Core控制臺程序演示 一、單層結(jié)構(gòu)的配置1 using Microsoft.Extensions.Configuration; 2 using Microsoft.Extensions.Configuration.Memory; 3 using System; 4 using System.Collections.Generic; 5 6 namespace DiApplicationTest 7 { 8 public class Program 9 { 10 public static void Main(string[] args) 11 { 12 IDictionary<string, string> source = new Dictionary<string, string>() 13 { 14 ["Ele1"] = "value1", 15 ["Ele2"] = "value2" 16 }; 17 18 IConfiguration config = new ConfigurationBuilder().Add(new MemoryConfigurationSource() { InitialData = source }).Build(); 19 Console.WriteLine($"Ele1: {config["Ele1"]}"); 20 Console.WriteLine($"Ele2: {config["Ele2"]}"); 21 22 Console.ReadLine(); 23 } 24 } 25 } 啟動調(diào)試,查看cmd窗口輸出內(nèi)容 上面的例子里,將一個字典作為配置源讀入到config配置對象里,通過鍵可以讀取到對應(yīng)的值。 二、多層結(jié)構(gòu)的配置在大多數(shù)情況下,項目里的配置都是多層結(jié)構(gòu)的,也可以稱為是結(jié)構(gòu)化的。在上面的例子的基礎(chǔ)上稍加修改,實現(xiàn)結(jié)構(gòu)化的配置讀取。 1 using Microsoft.Extensions.Configuration; 2 using Microsoft.Extensions.Configuration.Memory; 3 using System; 4 using System.Collections.Generic; 5 6 namespace DiApplicationTest 7 { 8 public class Program 9 { 10 public static void Main(string[] args) 11 { 12 IDictionary<string, string> source = new Dictionary<string, string>() 13 { 14 ["Ele1"] = "value1", 15 ["Ele2:Sub1"] = "value2.1", 16 ["Ele2:Sub2"] = "value2.2" 17 }; 18 19 IConfiguration config = new ConfigurationBuilder().Add(new MemoryConfigurationSource() { InitialData = source }).Build(); 20 Console.WriteLine($"Ele1: {config["Ele1"]}"); 21 Console.WriteLine($"Ele2.Sub1: {config.GetSection("Ele2")["Sub1"]}"); 22 Console.WriteLine($"Ele2.Sub2: {config.GetSection("Ele2")["Sub2"]}"); 23 24 Console.ReadLine(); 25 } 26 } 27 } 啟動調(diào)試,查看cmd窗口輸出內(nèi)容 在這個例子里,字典內(nèi)容描述了一個具有兩層結(jié)構(gòu)的配置,第一層有Ele1和Ele2兩個節(jié)點(diǎn),分別對應(yīng)一個字符內(nèi)容和一個復(fù)合內(nèi)容,第二層有Sub1和Sub2兩個節(jié)點(diǎn),同時掛在Ele2節(jié)點(diǎn)下,組成了一個復(fù)合結(jié)構(gòu)。 注意看字典項里的Key,因為字典里的數(shù)據(jù)是扁平化的,為了能清晰描述節(jié)點(diǎn)之間的上下層關(guān)系,需要通過“:”符號來標(biāo)識。 config對象通過GetSection方法來獲取當(dāng)前節(jié)點(diǎn)的某個下級節(jié)點(diǎn)內(nèi)容。
第二部分、其他配置來源除了上面例子里展示的配置源來自內(nèi)存內(nèi)容,也可以來自Xml文件、JSON文件或者數(shù)據(jù)庫等。因為在.Net Core里使用JSON文件描述配置內(nèi)容很常見,下面就展示如何讀取JSON配置文件。 先添加如下兩個nuget包,支持從json文件讀取內(nèi)容 "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0", "Microsoft.Extensions.Configuration.Json": "1.0.0", 添加 appsettings.json 文件 修改Main函數(shù)內(nèi)容 1 using Microsoft.Extensions.Configuration; 2 using System; 3 using System.IO; 4 5 namespace DiApplicationTest 6 { 7 public class Program 8 { 9 public static void Main(string[] args) 10 { 11 IConfigurationBuilder builder = new ConfigurationBuilder(); 12 builder.SetBasePath(Directory.GetCurrentDirectory()); 13 builder.AddJsonFile("appsettings.json"); 14 15 IConfiguration config = builder.Build(); 16 Console.WriteLine($"Ele1: {config["Ele1"]}"); 17 Console.WriteLine($"Ele2.Sub1: {config.GetSection("Ele2")["Sub1"]}"); 18 Console.WriteLine($"Ele2.Sub2: {config.GetSection("Ele2")["Sub2"]}"); 19 20 Console.ReadLine(); 21 } 22 } 23 } 啟動調(diào)試,查看cmd窗口輸入內(nèi)容,與上面的例子內(nèi)容一致。 這個例子將原來在字典里的內(nèi)容轉(zhuǎn)換成Json格式化的內(nèi)容存儲在持久化文件里。通過指定配置源,同樣可以讀取內(nèi)容。
第三部分、Options對象映射當(dāng)配置文件內(nèi)容較多時,通過config的Key獲取對應(yīng)的配置項的值變得比較繁瑣。.Net Core的配置系統(tǒng)采用了一種叫“Options Pattern”的模式使配置內(nèi)容與有著對應(yīng)結(jié)構(gòu)的對象進(jìn)行映射,這種對象就叫做Options對象。 下面將簡單演示一下這種映射方式。 首先添加如下nuget包引用,使用此模式的相關(guān)接口和類都在這個包里。同時還需要引入DI容器。 "Microsoft.Extensions.DependencyInjection": "1.0.0", "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0", 添加兩個具有層級結(jié)構(gòu)的Options類 1 public class ConfigOptions 2 { 3 public string Ele1 { get; set; } 4 public SubConfigOptions Ele2 { get; set; } 5 } 6 7 public class SubConfigOptions 8 { 9 public string Sub1 { get; set; } 10 public string Sub2 { get; set; } 11 } 修改Main函數(shù)內(nèi)容 1 public static void Main(string[] args) 2 { 3 // 創(chuàng)建DI容器,注冊O(shè)ptions Pattern服務(wù) 4 IServiceCollection services = new ServiceCollection(); 5 services.AddOptions(); 6 7 // 讀取配置文件 8 IConfigurationBuilder builder = new ConfigurationBuilder(); 9 builder.SetBasePath(Directory.GetCurrentDirectory()); 10 builder.AddJsonFile("appsettings.json"); 11 IConfiguration config = builder.Build(); 12 13 // 通過注冊的服務(wù)獲取最終映射的配置對象 14 IServiceProvider serviceProvider = services.Configure<ConfigOptions>(config).BuildServiceProvider(); 15 ConfigOptions options = serviceProvider.GetService<IOptions<ConfigOptions>>().Value; 16 17 Console.WriteLine($"Ele1: {options.Ele1}"); 18 Console.WriteLine($"Ele2.Sub1: {options.Ele2.Sub1}"); 19 Console.WriteLine($"Ele2.Sub2: {options.Ele2.Sub2}"); 20 21 Console.ReadLine(); 22 } 啟動調(diào)試,查看cmd窗口輸入內(nèi)容,與上面的例子內(nèi)容一致。 在定義Options對象結(jié)構(gòu)時,對象內(nèi)的屬性名稱要與對應(yīng)層級的配置Key的值保持一致,層級關(guān)系也要與配置內(nèi)容的層級結(jié)構(gòu)保持一致。 通過調(diào)用 services.AddOptions() 方法注冊O(shè)ptions Pattern服務(wù)。將配置內(nèi)容注冊到容器里,來獲取對應(yīng)的服務(wù)Provider對象。通過調(diào)用GetService方法獲得對應(yīng)的真實服務(wù)對象,即帶有事先定義的Options類型的泛型接口IOptions,接口的Value值就是配置內(nèi)容映射的Options對象。
第四部分、Asp.Net Core里的配置管理在這個系列之前使用的例子里添加配置管理相關(guān)的功能,來修改初始化日志級別的代碼,同時添加一些自定義配置。 先添加配置相關(guān)的nuget包 "Microsoft.Extensions.Configuration": "1.0.0", "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0", "Microsoft.Extensions.Configuration.Json": "1.0.0", "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0" 添加appsettings.json文件 1 { 2 // 日志配置 3 "Logging": { 4 "LogLevel": { 5 "Microsoft": "Warning" 6 } 7 }, 8 // 自定義配置 9 "CfgContent": { 10 "Ele1": "value1", 11 "Ele2": { 12 "Sub1": "value2.1", 13 "Sub2": "value2.2" 14 } 15 } 16 } 添加上個例子里的 ConfigOptions.cs、SubConfigOptions.cs 類,修改 Startup.cs 的內(nèi)容,添加配置相關(guān)代碼 1 using System.IO; 2 using Microsoft.AspNetCore.Builder; 3 using Microsoft.Extensions.Configuration; 4 using Microsoft.Extensions.DependencyInjection; 5 using Microsoft.Extensions.Logging; 6 7 namespace WebApiFrame 8 { 9 public class Startup 10 { 11 public IConfiguration Configuration { get; } 12 13 public Startup() 14 { 15 var builder = new ConfigurationBuilder() 16 .SetBasePath(Directory.GetCurrentDirectory()) 17 .AddJsonFile("appsettings.json"); 18 19 Configuration = builder.Build(); 20 } 21 22 public void ConfigureServices(IServiceCollection services) 23 { 24 services.AddOptions(); 25 services.Configure<ConfigOptions>(Configuration.GetSection("CfgContent")); 26 27 // 注入MVC框架 28 services.AddMvc(); 29 } 30 31 public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) 32 { 33 // 添加日志支持 34 loggerFactory.AddConsole(Configuration.GetSection("Logging")); 35 loggerFactory.AddDebug(); 36 37 // 添加NLog日志支持 38 //loggerFactory.AddNLog(); 39 40 // 添加MVC中間件 41 app.UseMvc(); 42 } 43 } 44 } 修改 DemoController.cs 內(nèi)容 1 using System.Threading.Tasks; 2 using Microsoft.AspNetCore.Http; 3 using Microsoft.AspNetCore.Mvc; 4 using Microsoft.Extensions.Options; 5 6 namespace WebApiFrame 7 { 8 [Route("[controller]")] 9 public class DemoController : Controller 10 { 11 private ConfigOptions _cfgContent { get; } 12 13 public DemoController(IOptions<ConfigOptions> options) 14 { 15 _cfgContent = options.Value; 16 } 17 18 [HttpGet("index")] 19 public async Task Index() 20 { 21 HttpContext.Response.ContentType = "text/html"; 22 await HttpContext.Response.WriteAsync($"<span>Ele1: {_cfgContent.Ele1}</span><br />"); 23 await HttpContext.Response.WriteAsync($"<span>Ele2.Sub1: {_cfgContent.Ele2.Sub1}</span><br />"); 24 await HttpContext.Response.WriteAsync($"<span>Ele2.Sub2: {_cfgContent.Ele2.Sub2}</span><br />"); 25 } 26 } 27 } 啟動調(diào)試,訪問地址 http://localhost:5000/demo/index ,頁面顯示配置內(nèi)容 從這個例子里可以看到,讀取 appsettings.json 配置文件內(nèi)容并分成兩部分,其中一部分配置Logging作為Logger的配置內(nèi)容用于日志初始化,另外一部分CfgContent配置內(nèi)容注冊到DI容器,在控制器的構(gòu)造函數(shù)里通過IOptions泛型類型的參數(shù)注入,這樣控制器就可以讀取配置文件的內(nèi)容。 |
|