問題
如何在 ASP.NET Core 2.0 應用程序中讀取全局配置項?
答案
首先新建一個空項目,并添加兩個配置文件:
1. appsettings.json
{ "Section1": { "SettingA": "ValueA", "SettingB": "ValueB" }, "Section2": { "SettingC": "ValueC" } }
2. appsettings.Development.json
{ "Section1": { "SettingA": "Dev_ValueA" }, "Section2": { "SettingC": "Dev_ValueC" } }
Visual Studio會自動識別兩者的關系,并在解決方案層次結構中展示如下:
然后創建相應的POCO類,分別對應于幾個配置節點:
public class AppSettings { public AppSettingsSection1 Section1 { get; set; } public AppSettingsSection2 Section2 { get; set; } } public class AppSettingsSection1 { public string SettingA { get; set; } public string SettingB { get; set; } } public class AppSettingsSection2 { public string SettingC { get; set; } }
在Startup.cs文件中,創建接收 IConfiguration 的構造函數:
public static IConfiguration Configuration { get; private set;} public Startup(IConfiguration config) { Configuration = config; }
然后在 ConfigureServices() 方法中添加Options服務,并設置依賴項:
public void ConfigureServices(IServiceCollection services) { services.AddOptions(); services.Configure<AppSettings>(Configuration); }
最后,將配置項作為IOptions接口注入中間件的構造函數,其中泛型類型T就是我們剛才定義的POCO類:
public class HelloWorldMiddleware { private readonly RequestDelegate _next; private readonly AppSettings _settings; public HelloWorldMiddleware(RequestDelegate next, IOptions<AppSettings> options) { _next = next; _settings = options.Value; } public async Task Invoke(HttpContext context) { var jsonSettings = JsonConvert.SerializeObject(_settings, Formatting.Indented); await context.Response.WriteAsync(jsonSettings); } } public static class UseHelloWorldInClassExtensions { public static IApplicationBuilder UseHelloWorld(this IApplicationBuilder app) { return app.UseMiddleware<HelloWorldMiddleware>(); } }
在Startup.cs的 Configure() 方法中,將此中間件注入到請求管道中:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseHelloWorld(); }
運行,此時頁面顯示:
討論
ASP.NET Core 擁有一個簡單的機制來從各種數據源(比如JSON文件,環境變量,甚至是自定義數據源)中讀取應用程序設置。然后通過依賴注入,方便的使用這些配置項。
盡管這一切看起來很魔幻(我們的設置究竟是如何加載的!),ASP.NET Core 2.0隱藏了從數據源中讀取配置項的細節,這些內容本應該存在于Program.cs文件中WebHost的CreateDefaultBuilder()方法中。IConfiguration隨后被添加到服務容器中,并在應用程序的其他部分保持可用,我們使用Startup中的此接口來添加配置項。為了觀察這個過程,請將Program.cs文件中的BuildWebHost()方法替換為如下內容,得到的結果是一樣的:
public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .ConfigureAppConfiguration((context, builder) => { var env = context.HostingEnvironment; builder.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true); if (env.IsDevelopment()) { var appAssembly = Assembly.Load( new AssemblyName(env.ApplicationName)); if (appAssembly != null) { builder.AddUserSecrets(appAssembly, optional: true); } } builder.AddEnvironmentVariables(); if (args != null) { builder.AddCommandLine(args); } }) .Build();
在上面的解決方案中,我們提供了兩個JSON文件數據源。需要記著的一點是,這些文件按照順序被依次讀取,后面的數據源會覆蓋前面的數據源。你也可以在上面的運行結果中注意到,SettingB配置項來自于第一個配置文件,而其他兩個配置項都來自于第二個配置文件。
注意:Startup.cs中的IConfiguration實例擁有public static修飾符,因此可以在整個應用程序期間使用此實例:
var valueA = Config["Section1:SettingA"];
然而,更好的辦法是將配置項讀入一個類型化的POCO類,并將其作為依賴項注入中間件或者控制器。上面的示例正好展示了這個模式。
你也可以為不同的配置節定義不同的POCO類,并使用IConfiguration的GetSection()方法來讀取。
====start by sanshi=========================
下面我們簡單擴展之前的示例,來讀取不同的配置節:
public void ConfigureServices(IServiceCollection services) { services.AddOptions(); services.Configure<AppSettings>(Configuration); services.Configure<AppSettingsSection1>(Configuration.GetSection("Section1")); }
更新中間件代碼,此時向中間件的構造函數注入兩個依賴項:
public class HelloWorldMiddleware { private readonly RequestDelegate _next; private readonly AppSettings _settings; private readonly AppSettingsSection1 _settingsSection1; public HelloWorldMiddleware(RequestDelegate next, IOptions<AppSettings> options, IOptions<AppSettingsSection1> optionsSection1) { _next = next; _settings = options.Value; _settingsSection1 = optionsSection1.Value; } public async Task Invoke(HttpContext context) { var jsonSettings = JsonConvert.SerializeObject(_settings, Formatting.Indented); var jsonSettingsSection1 = JsonConvert.SerializeObject(_settingsSection1, Formatting.Indented); await context.Response.WriteAsync("AppSettings:\n" + jsonSettings + "\n\nAppSettings - Section1:\n" + jsonSettingsSection1); } }
運行,此時頁面顯示:
====end by sanshi=========================
當然,我們也可以手工設置配置項的值,通過使用IServiceCollection.Configure的重載方法并接收強類型的lambda表達式:
====start by sanshi=========================
修改ConfigurationServices()方法,手工設置配置項:
public void ConfigureServices(IServiceCollection services) { services.AddOptions(); services.Configure<AppSettings>(options => { options.Section1 = new AppSettingsSection1(); options.Section1.SettingA = "SettingA Value"; options.Section1.SettingB = "SettingB Value"; }); }
運行,此時頁面效果:
====end by sanshi=========================
源代碼下載
原文:https://tahirnaushad.com/2017/08/15/asp-net-core-configuration/
文章列表