Tuỳ chỉnh cấu hình ứng dụng ASP.NET 6.0

Giới thiệu về cấu hình trong ASP.NET 6.0

Trong bài viết này, chúng ta sẽ khám phá cách tuỳ chỉnh cấu hình ứng dụng trong .NET 6.0. Cấu hình là một phần không thể thiếu trong hầu hết các ứng dụng, và ASP.NET Core cung cấp nhiều linh hoạt để quản lý và mở rộng cơ chế cấu hình.

Chúng ta sẽ tập trung vào các chủ đề sau:

  • Thiết lập tệp cấu hình
  • Sử dụng cấu hình kiểu mạnh (typed configuration)
  • Cấu hình với tệp INI
  • Cung cấp cấu hình (configuration providers)

Thiết lập tệp cấu hình

Từ ASP.NET Core 2.0, cấu hình đã được tách khỏi file Startup.cs để giữ cho nó sạch sẽ và đơn giản. Trong ASP.NET Core 3.1 đến 5.0, chúng ta sử dụng mẫu code sau:

public class Program 
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();    
    }    

    public static IHostBuilder CreateWebHostBuilder(string[] args) => 
        Host.CreateDefaultBuilder(args).
        ConfigureWebHostDefaults(webBuilder =>{ 
            webBuilder.UseStartup(); 
        });
}

Tuy nhiên, trong ASP.NET 6.0, Microsoft đã giới thiệu phương pháp API tối thiểu (minimal API) bằng cách loại bỏ file Startup.cs và đặt tất cả cấu hình vào file Program.cs:

var builder = WebApplication.CreateBuilder(args); 
// Thêm dịch vụ vào container. 
builder.Services.AddControllersWithViews(); 
var app = builder.Build();

Cả hai phiên bản đều hỗ trợ cấu hình mặc định và cho phép tuỳ chỉnh. Chúng ta có thể sử dụng phương thức ConfigureAppConfiguration() để mở rộng IWebHostBuilder:

Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>
{        
    webBuilder.ConfigureAppConfiguration((builderContext,config) =>
    {            
        // Nội dung cấu hình ở đây     
    }).UseStartup();    
});

Chúng ta cũng có thể cấu hình ứng dụng bằng cách truy cập thuộc tính Configuration của builder:

builder.Configuration.AddJsonFile("appsettings.json",optional: false,reloadOnChange: true);

Mặc định, khi tạo dự án ASP.NET Core, các tệp cấu hình như appsettings.json và appsettings.Development.json sẽ được tạo ra. Code đọc mặc định cho appsettings.json như sau:

var env = builder.Environment; 
builder.Configuration.SetBasePath(env.ContentRootPath); 
builder.Configuration.AddJsonFile("appsettings.json",optional: false,reloadOnChange:true); 
builder.Configuration.AddJsonFile($"appsettings.{env.EnvironmentName}.json",optional:true,reloadOnChange:true); 
builder.Configuration.AddEnvironmentVariables();

Việc sử dụng AddEnvironmentVariables() là một phương pháp tốt nhất. Thứ tự cấu hình rất quan trọng, các cấu hình được thêm sau sẽ ghi đè lên các cấu hình được thêm trước. Trong trường hợp này, biến môi trường luôn được áp dụng cuối cùng.

IConfigurationBuilder cung cấp nhiều phương thức mở rộng để thêm các cấu hình khác như XML, INI, hoặc cấu hình trong bộ nhớ. Cộng đồng cũng đã phát triển nhiều nhà cung cấp cấu hình khác để đọc tệp YAML, giá trị từ cơ sở dữ liệu, v.v.

Sử dụng cấu hình kiểu mạnh

Thay vì đọc cấu hình từng khóa bằng IConfiguration, chúng ta nên sử dụng cấu hình kiểu mạnh. Để thực hiện điều này, chúng ta cần định nghĩa một lớp cho cấu hình. Ví dụ, tạo một lớp tên là AppSettings:

namespace ConfigDemo; 
public class AppSettings {     
    public int Foo { get; set; }     
    public string Bar { get; set; }
}

Đây là một lớp POCO đơn giản. Trong ASP.NET Core 5.0, chúng ta có thể điền các lớp này trong phương thức ConfigureServices của Startup.cs:

services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));

Với phương pháp mini API, cấu hình sẽ như sau:

builder.Services.Configure<AppSettings>(builder.Configuration.GetSection("AppSettings"));

Bằng cách này, cấu hình kiểu mạnh có thể được đăng ký như một dịch vụ trong container dependency injection (DI) và sử dụng ở bất kỳ đâu trong ứng dụng. Chúng ta có thể tạo các loại cấu hình khác nhau cho từng phần cấu hình.

Dưới đây là ví dụ sử dụng cấu hình kiểu trong MVC controller:

using Microsoft.Extensions.Options; 
// ... 
public class HomeController : Controller {     
    private readonly AppSettings _options;     
    public HomeController(IOptions<AppSettings> options)     
    {         
        _options = options.Value;     
    }     
    public IActionResult Index()     
    {         
        ViewData["Message"] = _options.Bar;         
        return View();     
    }
}

IOptions là một wrapper cho kiểu AppSettings, thuộc tính Value chứa thể hiện của lớp AppSettings với các giá trị từ tệp cấu hình.

Để đọc các cài đặt, chúng ta cần thêm phần AppSettings vào tệp appsettings.json:

{
    "Logging": { "LogLevel": { "Default": "Warning" }},
    "AllowedHosts": "*", 
    "AppSettings": {"Foo": 123,"Bar": "Bar"} 
}

Cấu hình với tệp INI

Để sử dụng tệp INI cho cấu hình ứng dụng, chúng ta cần thêm cấu hình INI trong phương thức ConfigureAppConfiguration() của Program.cs:

builder.Configuration.AddIniFile("appsettings.ini",optional: false,reloadOnChange: true); 
builder.Configuration.AddJsonFile($"appsettings.{env.EnvironmentName}.ini", optional: true, reloadOnChange: true);

Cách này tương tự như việc tải tệp cấu hình JSON. Dòng đầu tiên là cấu hình bắt buộc, dòng thứ hai là tệp cấu hình tùy chọn phụ thuộc vào môi trường runtime hiện tại.

Tệp INI có thể trông như sau:

[AppSettings] Bar="FooBar"

Tệp này chứa một phần tên là AppSettings với một thuộc tính tên là Bar.

Thứ tự cấu hình rất quan trọng. Nếu chúng ta thêm hai dòng cấu hình cho tệp INI sau khi cấu hình bằng tệp JSON, thì tệp INI sẽ ghi đè các cài đặt trong tệp JSON, và giá trị của thuộc tính Bar sẽ được thay thế bằng FooBar.

Nhà cung cấp cấu hình

Nhà cung cấp cấu hình (configuration provider) là triển khai của IConfigurationProvider, được tạo ra từ nguồn cấu hình (triển khai của IConfigurationSource). Nhà cung cấp cấu hình đọc dữ liệu từ nguồn và cung cấp dữ liệu qua cấu trúc dictionary.

Để thêm nhà cung cấp cấu hình tùy chỉnh hoặc của bên thứ ba vào ASP.NET Core, chúng ta cần gọi phương thức Add trên ConfigurationBuilder để thêm nguồn cấu hình:

// thêm nguồn cấu hình mới 
builder.Configuration.Add(new MyCustomConfigurationSource { 
    SourceConfig = // nguồn dữ liệu cấu hình     
    Optional = false,  
    ReloadOnChange = true 
});

Thông thường, chúng ta tạo một phương thức mở rộng để thêm nguồn cấu hình một cách trau chuốt hơn:

builder.Configuration.AddMyCustomSource("source", optional: false, reloadOnChange: true);

Kết luận

Trong大多数情况下, chúng ta không cần thêm các nhà cung cấp cấu hình khác hoặc tạo nhà cung cấp cấu hình riêng, nhưng việc biết cách tuỳ chỉnh chúng là hữu ích. Ngoài ra, sử dụng cấu hình kiểu mạnh là một cách tốt để đọc và cung cấp cài đặt. Trong ASP.NET truyền thống, chúng ta thường đọc cấu hình một cách thủ công, nhưng giờ đây, chỉ cần cung cấp một kiểu là tự động hoàn thành công việc, vì kiểu này sẽ được tự động khởi tạo qua DI.

Thẻ: ASP.NET Core .NET 6 Configuration Minimal API Dependency Injection

Đăng vào ngày 18 tháng 5 lúc 15:59