0Pricing
C# Academy · Pelajaran

Validasi Options & Options Bernama

Validasi options saat startup dengan DataAnnotations atau FluentValidation, dan gunakan options bernama untuk beberapa instance.

Validasi Options & Options Bernama adalah pelajaran C# Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar C# Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus C# Academy mencakup 4 pelajaran total.

Mengapa Memvalidasi Options?

Konfigurasi yang hilang atau formatnya salah menyebabkan kesalahan saat program berjalan yang sulit dilacak. Memvalidasi options saat mulai mengubah masalah konfigurasi tersembunyi menjadi pengecualian yang langsung terlihat dan deskriptif sebelum permintaan apa pun dilayani.

ValidateOnStart

ValidateOnStart() memicu validasi segera saat aplikasi mulai, bukan secara malas saat pertama kali digunakan. Artinya, penerapan yang salah konfigurasi langsung gagal, bukan beberapa jam kemudian.

builder.Services
    .AddOptions<DatabaseOptions>()
    .BindConfiguration("Database")
    .ValidateDataAnnotations()
    .ValidateOnStart(); // throw OptionsValidationException on startup

// Without ValidateOnStart:
// - Validation only runs on first IOptions<T>.Value access
// - A rarely-used service could run for hours before failing

// With ValidateOnStart:
// - App fails at Host.Run() if config is invalid
// - Health checks and probes never report healthy for bad config

Validasi DataAnnotations

Gunakan atribut standar System.ComponentModel.DataAnnotations pada kelas options Anda. Atribut tersebut dievaluasi secara otomatis oleh ValidateDataAnnotations().

using System.ComponentModel.DataAnnotations;

public class EmailOptions
{
    [Required(ErrorMessage = "SMTP host is required")]
    [MinLength(3)]
    public string SmtpHost { get; set; } = string.Empty;

    [Range(1, 65535, ErrorMessage = "Port must be 1-65535")]
    public int SmtpPort { get; set; } = 587;

    [Required]
    [EmailAddress(ErrorMessage = "Invalid sender address")]
    public string SenderAddress { get; set; } = string.Empty;

    [Range(1, 30)]
    public int TimeoutSeconds { get; set; } = 10;
}

builder.Services
    .AddOptions<EmailOptions>()
    .BindConfiguration("Email")
    .ValidateDataAnnotations()
    .ValidateOnStart();

Delegasi Validasi Kustom

Overload Validate(Func<T, bool>, string) menambahkan fungsi lambda untuk aturan yang tidak dapat dinyatakan dengan atribut, seperti batasan lintas properti.

builder.Services
    .AddOptions<ConnectionPoolOptions>()
    .BindConfiguration("ConnectionPool")
    .ValidateDataAnnotations()
    .Validate(
        opts => opts.MaxSize >= opts.MinSize,
        "MaxSize must be greater than or equal to MinSize")
    .Validate(
        opts => opts.ConnectionTimeoutMs > 0,
        "ConnectionTimeoutMs must be positive")
    .ValidateOnStart();

public class ConnectionPoolOptions
{
    [Range(1, 100)] public int MinSize { get; set; } = 2;
    [Range(1, 500)] public int MaxSize { get; set; } = 20;
    public int ConnectionTimeoutMs { get; set; } = 5000;
}

IValidateOptions untuk Aturan Kompleks

Untuk logika kompleks dengan beberapa pesan kesalahan, implementasikan IValidateOptions<T>. Komponen ini menerima instans options dan mengembalikan hasil dengan pesan kegagalan yang terperinci.

public class PaymentOptionsValidator : IValidateOptions<PaymentOptions>
{
    public ValidateOptionsResult Validate(string? name, PaymentOptions opts)
    {
        var failures = new List<string>();

        if (opts.Provider == "Stripe" && string.IsNullOrWhiteSpace(opts.StripeSecretKey))
            failures.Add("StripeSecretKey is required when Provider is Stripe");

        if (opts.Provider == "PayPal" && string.IsNullOrWhiteSpace(opts.PayPalClientId))
            failures.Add("PayPalClientId is required when Provider is PayPal");

        if (opts.RetryCount < 0 || opts.RetryCount > 5)
            failures.Add("RetryCount must be between 0 and 5");

        return failures.Count == 0
            ? ValidateOptionsResult.Success
            : ValidateOptionsResult.Fail(failures);
    }
}

builder.Services.AddSingleton<IValidateOptions<PaymentOptions>, PaymentOptionsValidator>();

Options Bernama — Konsep

Options bernama memungkinkan Anda mendaftarkan beberapa konfigurasi dari tipe options yang sama. Kasus penggunaan umum: beberapa klien HTTP keluar, masing-masing dengan URL dasar dan batas waktu yang berbeda.

// appsettings.json:
{
  "HttpClients": {
    "Orders": {
      "BaseUrl": "https://orders-service",
      "TimeoutSeconds": 30
    },
    "Inventory": {
      "BaseUrl": "https://inventory-service",
      "TimeoutSeconds": 10
    }
  }
}

public class HttpClientOptions
{
    public string BaseUrl { get; set; } = string.Empty;
    public int TimeoutSeconds { get; set; } = 30;
}

Mendaftarkan Options Bernama

Teruskan string nama sebagai argumen pertama ke Configure<T>. Gunakan IOptionsMonitor<T>.Get(name) untuk mendapatkan instans tertentu.

// Register:
builder.Services.Configure<HttpClientOptions>("Orders",
    builder.Configuration.GetSection("HttpClients:Orders"));
builder.Services.Configure<HttpClientOptions>("Inventory",
    builder.Configuration.GetSection("HttpClients:Inventory"));

// Consume:
public class ApiGateway
{
    private readonly HttpClientOptions _orders;
    private readonly HttpClientOptions _inventory;

    public ApiGateway(IOptionsMonitor<HttpClientOptions> monitor)
    {
        _orders    = monitor.Get("Orders");
        _inventory = monitor.Get("Inventory");
    }

    // IOptions<T>.Value always returns the unnamed (default) instance
    // IOptionsMonitor<T>.Get(name) returns the named instance
}

Options Bernama dengan Validasi

Validasi options bernama secara terpisah dengan memanggil AddOptions<T>(name) untuk setiap pendaftaran bernama.

foreach (var clientName in new[] { "Orders", "Inventory", "Auth" })
{
    builder.Services
        .AddOptions<HttpClientOptions>(clientName)
        .BindConfiguration($"HttpClients:{clientName}")
        .ValidateDataAnnotations()
        .Validate(
            opts => Uri.IsWellFormedUriString(opts.BaseUrl, UriKind.Absolute),
            $"HttpClients:{clientName}:BaseUrl must be a valid absolute URI")
        .ValidateOnStart();
}

// If any named instance fails, the app refuses to start

API OptionsBuilder

OptionsBuilder<T> (yang dikembalikan oleh AddOptions<T>()) adalah API fluent yang merangkai semua langkah pendaftaran, pengikatan, dan validasi dengan rapi.

// Full OptionsBuilder chain:
builder.Services
    .AddOptions<DatabaseOptions>()        // create builder
    .BindConfiguration("Database")         // bind JSON section
    .Configure(opts =>                     // manual override
    {
        if (builder.Environment.IsDevelopment())
            opts.EnableDetailedErrors = true;
    })
    .PostConfigure(opts =>                 // runs after all Configure
    {
        opts.ConnectionString ??= "default-fallback";
    })
    .ValidateDataAnnotations()             // attribute rules
    .Validate(o => o.MaxPoolSize > 0,
              "MaxPoolSize must be positive")
    .ValidateOnStart();                    // eager validation

Penerapan di Dunia Nyata: Options Kebijakan Percobaan Ulang

Penyiapan options percobaan ulang yang lengkap dengan validasi lintas bidang dan kebijakan bernama untuk berbagai layanan.

public class RetryOptions
{
    [Range(0, 10)] public int MaxAttempts { get; set; } = 3;
    [Range(100, 60000)] public int BaseDelayMs { get; set; } = 500;
    public bool UseExponentialBackoff { get; set; } = true;
    [Range(1, 120000)] public int MaxDelayMs { get; set; } = 30000;
}

foreach (var policy in new[] { "Database", "HttpClient", "MessageBus" })
{
    builder.Services
        .AddOptions<RetryOptions>(policy)
        .BindConfiguration($"RetryPolicies:{policy}")
        .Validate(o => !o.UseExponentialBackoff || o.MaxDelayMs > o.BaseDelayMs,
                  "MaxDelayMs must exceed BaseDelayMs when using exponential backoff")
        .ValidateOnStart();
}

Pemeriksaan Singkat

Apa manfaat memanggil ValidateOnStart() saat mendaftarkan options?

Ringkasan: Validasi Options & Options Bernama

Poin penting:

  • ValidateOnStart(): gagal saat mulai, bukan saat pertama kali digunakan
  • DataAnnotations: [Required], [Range], dan lainnya + ValidateDataAnnotations()
  • Validate(Func, message): fungsi lambda sebaris untuk aturan lintas properti
  • IValidateOptions<T>: validasi terprogram menyeluruh dengan beberapa kesalahan
  • Options bernama: Configure<T>(name, ...) + IOptionsMonitor<T>.Get(name)
  • OptionsBuilder<T>: API fluent untuk merangkai semua langkah pendaftaran

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Validasi Options & Options Bernama” gratis?

Ya — teks lengkap “Validasi Options & Options Bernama” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus C# Academy, upgrade ke CoddyKit PRO. Kursus C# Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Validasi Options & Options Bernama”?

Validasi options saat startup dengan DataAnnotations atau FluentValidation, dan gunakan options bernama untuk beberapa instance. Kamu berlatih C# Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai C# Academy?

Tidak diperlukan pengalaman sebelumnya. C# Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.

Berapa lama pelajaran “Validasi Options & Options Bernama” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran C# Academy ini?

Ya. Setiap pelajaran C# Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Sumber & Penyedia Konfigurasi
  2. Options Bertipe Kuat dengan IOptions
  3. Validasi Options & Options Bernama
  4. Pengelolaan Rahasia
← Kembali ke C# Academy