Cấu hình hệ thống đã thay đổi rất nhiều trong ASP.NET Core. ASP.NET Cũ sử dụng file Web.Config để lưu thông tin cấu hình. Hệ thống mới giờ đây cung cấp hẳn API để làm việc với cấu hình và hỗ trợ nhiều định dạng file như JSON, XML, INI, tham số đầu vào từ dòng lệnh (command line arguments), biến môi trường (environment variables)…. Bài viết này chúng ta sẽ tìm hiểu về cách lưu trữ và đọc cấu hình từ file appsettings.json.
Cấu hình là gì?
Cấu hình là các tham số hoặc các cài đặt cụ thể cho ứng dụng. Các cài đặt này được lưu trữ riêng biệt trong code và trong các file độc lập. Nó giúp các developer và quản trị kiểm soát và dễ dàng thay đổi cách mà ứng dụng chạy.
Ví dụ: Connection Strings cần để kết nối đến cơ sở dữ liệu được lưu trong một file cấu hình. Bằng cách thay đổi chuỗi connection mà bạn có thể thay đổi tên cơ sở dữ liệu, vị trí… mà không cần thay đổi mã nguồn.
Ứng dụng ASP.NET sử dụng Web.Config để lưu trữ cấu hình. Ví dụ chuỗi kết nối được lưu như dưới đây:
<connectionStrings>
<add connectionString="data source=ABC;Integrated Security=SSPI;
initial catalog=xyz" providerName="System.Data.SqlClient"/>
</connectionStrings>
Cấu hình trong ASP.NET Core
Cấu hình trong ứng dụng ASP.NET Core được lưu dưới dạng cặp tên-giá trị. Bạn có thể lưu chúng trong file JSON, XML hay INI.
Ví dụ dưới đây hiển thị một cấu hình JSON đơn giản:
{
"option1": "value1",
"option2": 2
}
Cặp tên-giá trị này có thể được nhóm lại vào trong một cây đa cấp như dưới đây:
{
"subsection":
{
"suboption1": "subvalue1",
"suboption2": "subvalue2"
}
}
Đây cũng là điểm mới và mạnh hơn so với sử dụng Web.Config trước đây khi mà các cấu hình được nhóm lại từng nhóm và hỗ trợ nhiều cấp giúp quản lý cấu hình dễ dàng hơn. Ứng dụng ASP.NET Core đọc các file cấu hình từ lúc khởi động. Nó có thể được cấu hình để đọc trong lúc chạy nếu nó thay đổi.
Nguồn cấu hình
ASP.NET Core hỗ trợ đọc cấu hình từ các nguồn khác nhau và các định dạng khác nhau. Một vài nguồn được sử dụng phổ biến như:
- Định dạng file (JSON, INI hoặc XML)
- Command line Arguments (tham số dòng lệnh)
- Environment variables (biến môi trường)
- Custom Provider (cái này là tự tạo ra provider riêng theo ý muốn)
Load cấu hình
Mở Visual Studio 2017 và tạo một ứng dụng ASP.NET Core 2.2 Empty Project. Nếu bạn chưa biết hãy tham khảo bài viết Bắt đầu khởi tạo ứng dụng ASP.NET Core.
Mở Program.cs nó sẽ có phương thức Main, đây là điểm khởi đầu của ứng dụng chúng ta cũng có bài viết nói đến nó ở Khởi động ứng dụng trong ASP.NET Core
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
Phương thức Main gọi CreateDefaultBuilder là một helper class. Một trong các công việc mà CreateDefaultBuilder thực hiện là load cấu hình từ các nguồn:
.ConfigureAppConfiguration((hostingContext, config) => {
var env = hostingContext.HostingEnvironment;
config.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) {
config.AddUserSecrets(appAssembly, optional: true);
}
}
config.AddEnvironmentVariables();
if (args != null) {
config.AddCommandLine(args);
}
})
ConfigureAppConfiguration
Phương thức ConfigureAppConfiguration nhận 2 tham số. Tham số đầu tiên là HostingContext là một thể hiện của WebHostBuilderContext và thứ hai là biến config, thể hiện của IConfigurationBuilder. WebHostBuilderContext đưa ra thuojc tính HostingEnvironment nó giúp chúng ta biết được chúng ta đang chạy ở môi trường Development (IsDevelopment), Production (IsProduction) hay Staging (IsStaging).
IConfigurationBuilder đưa ra một số phương thức để load file cấu hình.
Load cấu hình từ file JSON
Phương thức AddJsonFile load cấu hình từ file JSON.
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
Tham số đầu tiên là tên của file JSON, đường dẫn tương đối đến ContentRoot.
Nếu tham số thứ 2 là optional là true, thì nó sẽ không sinh ra bất cứ lỗi gì nếu nó không tìm thấy file appsettings.json.
Tham số thứ 3 reloadOnChange nếu là true, nó sẽ load lại cấu hình nếu nội dung của file cấu hình thay đổi chúng ta không cần restart ứng dụng.
Dòng tiếp theo của mã nguồn sẽ load ra file json thứ 2 đúng với tên môi trường đang chạy: appsettings.{env.EnvironmentName}.json. Điều này giúp chúng ta có các cấu hình khác nhau cho môi môi trường như là appsettings.Development.json.
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
Load từ user secrets
Đây là tính năng mới trong ASP.NET Core khi mà cấu hình được lưu trữ bên ngoài mã nguồn. Nó được gọi là user secrets và chỉ có thể áp dụng cho môi trường Development. Điều này hữu ích trong trường hợp bạn có những cấu hình chỉ muốn sử dụng trên máy dev thôi, và không muốn nó nằm trong mã nguồn khi đưa code lên source control chung.
if (env.IsDevelopment()) {
var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
if (appAssembly != null) {
config.AddUserSecrets(appAssembly, optional: true);
}
}
Load cấu hình từ biến môi trường
Phương thức AddEnvironmentVariables() đọc tất cả các user và system environment variable trong hệ điều hành ra.
config.AddEnvironmentVariables();
Đọc từ command line arguments
Phương thức AddCommandLine đọc tất cả các tham số của dòng lệnh khi các bạn gọi ứng dụng bằng command line mà truyền các tham số.
if (args != null) {
config.AddCommandLine(args);
}
Đọc cấu hình
Template mặc định là Empty không tạo ra file appsettings.json. Tạo file appsetting.json trong thư mục gốc của ứng dụng. Và thêm cấu hình ví dụ vào đây. Các key của file cấu hình là không phân biệt chữ hoa chữ thường.
{
"message" : "Hello from configuration"
}
Sau đó hãy đọc thông số message này ra. Mở file Startup.cs. Using name space using Microsoft.Extensions.Configuration;
Để đọc cấu hình, chúng ta cần thể hiện của IConfiguration. Chúng ta có thể dùng dependency injection để lấy thể hiện của nó trong constructor của Startup class. Bạn có thể dùng kỹ thuật này tương tự với Controller.
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
Sau đó nhận giá trị với phương thức Configuration.GetSection:
await context.Response.WriteAsync("<div>" + Configuration.GetSection("message").Value + "</div>");
Đọc Connection String
Chuỗi kết nối đến cơ sở dữ liệu có thể được thêm vào dưới đây. Chuỗi kết nối MySQL và SQL được nhóm vào một section là ConnectionStrings hoặc một node nếu là XML
"ConnectionStrings" :
{
"MySQLConnection": "This is MySQL Connection",
"SQLConnection": "This is SQL Server Connection"
}
Mỗi một section hoặc 1 node được chia tách bằng dấu phẩy và giá trị của nó được lấy ra như sau:
await context.Response.WriteAsync("<div>" + Configuration.GetSection("ConnectionStrings:MySQLConnection").Value+"</div>");
await context.Response.WriteAsync("<div>" + Configuration.GetSection("ConnectionStrings:SQLConnection").Value + "</div>");
Đọc mảng từ file cấu hình
Bạn có thể sử dụng JSON với mảng như sau:
"wizards": [
{
"Name": "Gandalf",
"Age": "1000"
},
{
"Name": "Harry",
"Age": "17"
}
]
Để đọc được đoạn cấu hình trên chúng ta cần sử dụng index như là một phần được chia tách trong string bởi dấu hai chấm:
await context.Response.WriteAsync("<div>" + Configuration.GetSection("wizards:0:Name").Value + "</div>");
Command line
Hệ thống cấu hình có thể được load từ các tham số của dòng lệnh. Phương thức CreateDefaultBuilder tải các đối số của dòng lệnh sử dụng.
config.AddCommandLine(args);
Các đối số của dòng lệnh nên tuân theo các quy tắc cụ thể. Các đối số phải được truyền dạng cặp key-value. Mỗi cặp key value phải được cách nhau bởi dấu cách.
Mở file startup và đến phương thức Configure và thêm đoạn code:
await context.Response.WriteAsync("<div>" + Configuration.GetSection("Arg1").Value + "</div>");
await context.Response.WriteAsync("<div>" + Configuration.GetSection("Arg2").Value + "</div>");
Mở cửa dổ console và đến thư mục project sau đó gọi dotnet run với 2 tham số command line:
Dotnet run arg1=Hello arg2=World
Giá trị “Hello” và “World” được hiển thị trên trình duyệt với 2 dòng tách biệt.
Đọc biến môi trường
Phương thức config.AddEnvironmentVariables(); load biến môi trường vào bộ nhớ của configuration collection. Bạn có thể đọc như sau:
await context.Response.WriteAsync("<div>" + Configuration.GetSection("PATH").Value + "</div>");
Thêm file cấu hình theo ý muốn
Bạn cũng có thể thêm bất cứ file cấu hình tùy biến nào. Đây là một tính năng rất hay bạn có thể tạo ra các file cấu hình riêng cho từng module hoặc hệ thống. Nó giúp quản lý cấu hình dễ hơn.
Ví dụ tạo 1 file test.json trong thư mục gốc:
{
"testMessage": "Hello from test.json"
}
Giờ bạn hãy mở file Program.cs ra và sửa code:
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.AddJsonFile("Test.json", true, true);
})
.Build();
Giờ hệ thống cấu hình sẽ tự động thêm tất cả các cấu hình từ file test.json.
await context.Response.WriteAsync("<div>" + Configuration.GetSection("testMessage").Value + "</div>");
Thứ tự sắp xếp
Thứ tự file cấu hình nào sẽ được load trước sau nó phụ thuộc vào thằng nào được add vào sau sẽ được ghi đè thằng trước.
Tổng kết
Chúng ta đã tìm hiểu hệ thống quản lý cấu hình mới trong ASP.NET Core. ASP.NET Core Empty project đã cài đặt ứng dụng để đọc thông tin cấu hình từ appsettings.json, appsettings.{env.EnvironmentName}.json, user secrets, environment variabe, và từ command line. Chúng ta có thể mở rộng bằng cách add thêm các file tùy biến mà chúng ta muốn.
Trích nguồn từ: (https://www.tektutorialshub.com/)