Aplikasi yang nyata menyimpan pengaturannya di luar kode program, sehingga nilai seperti ambang batas dan alamat tujuan dapat diubah tanpa kompilasi ulang. Topik ini membahas pola appsettings.json yang menjadi kebiasaan umum di ekosistem .NET, beserta antarmuka IConfiguration yang membacanya. Pembahasan mencakup bentuk berkas konfigurasinya, pembangunan sumber konfigurasi lewat ConfigurationBuilder, pembacaan nilai bertingkat, dan pengikatan satu bagian konfigurasi menjadi objek.
Pola berkas appsettings.json#
Berkas appsettings.json berisi pasangan kunci dan nilai dalam bentuk JSON, dan kunci yang bertingkat ditulis sebagai objek yang bersarang. Berkas berikut dipakai sepanjang topik ini, yaitu berisi nama aplikasi dan satu bagian Sensor dengan tiga pengaturan di dalamnya.
{
"NamaAplikasi": "Perekam Sensor",
"Sensor": {
"Ambang": 30,
"IntervalDetik": 10,
"Aktif": true
}
}Penamaan kunci pada praktiknya dijaga konsisten dengan nama property kelas pengaturannya, sehingga pengikatan bagian menjadi objek tidak memerlukan pemetaan manual. Perbedaan huruf besar-kecil pada kunci diabaikan oleh binder, sedangkan JSON yang bersarang lebih dalam dari satu tingkat dipetakan ke property kelas yang juga bersarang. Nilai boolean pada bagian Sensor dibaca langsung menjadi bool oleh binding tanpa penguraian manual, dan kebiasaan ini membuat berkas konfigurasi dapat dibaca tanpa membaca kode pemakainya.
Tingkatan pada JSON diterjemahkan menjadi kunci bertingkat dengan pemisah titik dua, sehingga nilai Ambang di dalam bagian Sensor diakses lewat kunci Sensor:Ambang. Nilai angka pada JSON diambil sebagai string oleh pengindeks dan diubah ke tipe lain secara eksplisit, sedangkan binding ke objek menangani konversi tipe secara otomatis. Berkas ini diletakkan di folder yang sama dengan folder kerja program, dan namanya menyesuaikan isi SetBasePath pada bagian berikutnya.
Membangun dan membaca IConfiguration#
Sumber konfigurasi dirakit oleh ConfigurationBuilder sebelum dipakai. Metode SetBasePath menetapkan folder kerja pencarian berkas, AddJsonFile mendaftarkan appsettings.json sebagai sumber, dan Build menyatukan seluruh sumber menjadi IConfigurationRoot. Nilai tunggal dibaca melalui pengindeks yang mengembalikan string, sedangkan GetValue<T> mengambil nilai sekaligus mengonversinya ke tipe yang diminta. Contoh berikut membaca ketiga cara tersebut, termasuk pengikatan bagian Sensor menjadi objek PengaturanSensor.
#:package Microsoft.Extensions.Configuration.Json@10.0.0
#:package Microsoft.Extensions.Configuration.Binder@10.0.0
// Program: membaca appsettings.json lewat IConfiguration
using Microsoft.Extensions.Configuration;
IConfigurationRoot config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.Build();
Console.WriteLine($"Aplikasi: {config["NamaAplikasi"]}");
Console.WriteLine($"Ambang suhu: {config.GetValue<int>("Sensor:Ambang")}");
PengaturanSensor? pengaturan = config.GetSection("Sensor").Get<PengaturanSensor>();
Console.WriteLine($"Interval kirim: {pengaturan?.IntervalDetik} detik");
Console.WriteLine($"Perekaman aktif: {pengaturan?.Aktif}");
class PengaturanSensor
{
public int Ambang { get; set; }
public int IntervalDetik { get; set; }
public bool Aktif { get; set; }
}Aplikasi: Perekam Sensor
Ambang suhu: 30
Interval kirim: 10 detik
Perekaman aktif: TrueUntuk menjalankan program tersebut dari folder topik, gunakan perintah berikut.
# aktifkan .NET yang terpasang di sandbox
export DOTNET_ROOT=/home/kal/.dotnet PATH=/home/kal/.dotnet:$PATH DOTNET_CLI_TELEMETRY_OPTOUT=1 DOTNET_NOLOGO=1
# jalankan program contoh dari folder topik
dotnet run --file Program.csAplikasi: Perekam Sensor
Ambang suhu: 30
Interval kirim: 10 detik
Perekaman aktif: TruePengindeks config["NamaAplikasi"] mengembalikan string apa adanya, sedangkan GetValue<int> mengonversi teks "30" menjadi bilangan dan mengembalikan nilai default tipe itu apabila kunci tidak ditemukan. Metode GetValue<T> juga menerima argumen kedua berupa nilai default, misalnya GetValue("Sensor:Ambang", 25), yang dipakai apabila kuncinya tidak terdaftar. Nilai bertingkat dapat dibaca tanpa GetSection dengan menuliskan seluruh kuncinya, sedangkan GetSection lebih menguntungkan ketika satu bagian dibaca berkali-kali atau diikat menjadi objek. Metode GetSection("Sensor") menandai bagian Sensor sebagai lingkup pembacaan, dan Get<PengaturanSensor>() mengikat setiap kunci di dalamnya ke property kelas yang namanya sama. Argumen optional: false membuat pembangunan konfigurasi gagal apabila berkasnya tidak ada, dan reloadOnChange: true memantau perubahan berkas selama aplikasi berjalan.
Menumpuk sumber konfigurasi#
ConfigurationBuilder dirancang untuk menerima lebih dari satu sumber, dan urutan pendaftarannya menentukan sumber mana yang menimpa sumber lain. Metode AddJsonFile dapat dipanggil beberapa kali, misalnya membaca appsettings.json sebagai sumber dasar lalu appsettings.Development.json untuk lingkungan pengembangan, dan nilai pada sumber yang didaftarkan kemudian menggantikan nilai sebelumnya. Metode AddEnvironmentVariables menambahkan variabel lingkungan sebagai sumber terakhir, sehingga penyebaran layanan dapat menimpa pengaturan apa pun tanpa menyentuh berkas. Argumen optional: true berguna pada berkas tambahan yang kehadirannya belum pasti, karena pembangunan konfigurasi tetap berjalan apabila berkas itu tidak ada. Dengan pola ini, nilai default diletakkan di berkas, sedangkan nilai yang berbeda per lingkungan diletakkan pada sumber di atasnya. Urutan inilah yang menjelaskan posisi variabel lingkungan paling akhir, yaitu sebagai lapisan penimpa terakhir yang tidak memerlukan perubahan berkas sama sekali. Perubahan berkas yang dimantau reloadOnChange memicu token pemuatan ulang, dan aplikasi yang perlu bereaksi terhadap perubahan itu berlangganan melalui GetReloadToken.
Kesalahan umum#
Kesalahan pada topik ini umumnya menyangkut kunci yang tidak terdaftar dan lokasi berkas yang dicari, dan ketiganya mudah dihindari dengan pemeriksaan sederhana.
- Mengasumsikan kunci pasti ada. Pengindeks mengembalikan
nulluntuk kunci yang tidak terdaftar, dan pemakaian nilainya tanpa pemeriksaan memicuNullReferenceException. MetodeGetValue<T>dengan argumen nilai default memberikan pengganti yang aman. - Melupakan
SetBasePath. Tanpa penentuan folder dasar, pencarian berkas memakai folder bawaan yang tidak selalu sama dengan folder kerja program, sehinggaappsettings.jsonyang ada tetap dilaporkan tidak ditemukan. - Menyimpan kata sandi di appsettings.json. Berkas ini biasanya ikut terkomit ke repositori, sehingga rahasia ditempatkan pada variabel lingkungan atau alat manajemen rahasia yang disediakan lingkungannya.
Ringkasan#
appsettings.jsonmenyimpan pengaturan sebagai JSON bertingkat, dan kunci bertingkatnya diakses dengan pemisah titik dua sepertiSensor:Ambang.ConfigurationBuildermerakit sumber konfigurasi,AddJsonFilemendaftarkan berkasnya, danBuildmenghasilkanIConfigurationRoot.- Nilai dibaca lewat pengindeks,
GetValue<T>untuk konversi tipe, sertaGetSection(...).Get<T>()untuk mengikat satu bagian menjadi objek. - Sumber yang didaftarkan kemudian menimpa sumber sebelumnya, dan variabel lingkungan lazim ditempatkan paling akhir.
Referensi#
- Configuration in .NET — Microsoft Learn — Panduan konfigurasi .NET, mulai dari ConfigurationBuilder hingga pembacaan nilai.
- Configuration providers — Microsoft Learn — Daftar penyedia sumber konfigurasi dan aturan urutan penimpaannya.