Altbilgi içeriğine atla
Iron Academy Logo
C# öğrenin
C# öğrenin

Diğer Kategoriler

C#'ta Seçenekler Deseni

[[academy-video-youtube({"vid": "ko1Ie9gDydY", "start_time": "0", "title": "The Options Pattern in C#", "creator": "Tim Corey", "length": "10m 15s"})]]

.NET uygulamalarındaki yapılandırma genellikle appsettings.json, ortam değişkenleri veya kullanıcı gizli bilgileri içinde bulunur. Yapılandırma verilerini dosyadan çıkararak sınıflarınıza temiz ve test edilebilir bir şekilde getirmeniz, seçenekler deseniyle çözülür. JSON anahtarlarını manuel olarak okumak veya ham dizeleri dolaştırmak yerine, bir yapılandırma bölümünü güçlü bir şekilde yazılmış bir C# sınıfına bağlayıp, onu gerekli yere taşımak için bağımlılık enjeksiyonu kullanırsınız.

Tim Corey, "The Options Pattern in C#" adlı videosunda, Blazor sunucu uygulamasında her birini gösterip, uygulamanızda yapılandırma eksik veya hatalı olduğunda hızlıca başarısız olmasını sağlayacak şekilde doğrulama eklemeyi göstererek opsiyon deseni üç varyasyonunu (IOptions, IOptionsSnapshot, ve IOptionsMonitor) tanıtmaktadır. Eğer yapılandırma dosyalarını okuyan ve bağımlılık enjeksiyonu kullanan herhangi bir .NET projesi geliştiriyorsanız, bu desen temeldir.

Kurulum: POCO Model ve appsettings.json

[0:34 - 1:46] Tim, iki parçası zaten yerinde olan bir Blazor web uygulaması (sunucu tarafında işlenen, istemci tarafı etkileşimi olmayan) ile başlar. İlki, bir CloudInfo bölümünde üç anahtar-değer çifti ile appsettings.json içindeki bir bölümdür:

// appsettings.json
{
  "CloudInfo": {
    "Storage": "https://storage.example.com",
    "Website": "https://www.example.com",
    "API": "https://api.example.com"
  }
}
// appsettings.json
{
  "CloudInfo": {
    "Storage": "https://storage.example.com",
    "Website": "https://www.example.com",
    "API": "https://api.example.com"
  }
}

İkinci parça, JSON anahtarlarını yansıtan özellikleri olan, düz bir C# sınıfı (bir POCO) 'dir:

public class CloudInfoOptions
{
    public string Storage { get; set; }
    public string Website { get; set; }
    public string API { get; set; }
}
public class CloudInfoOptions
{
    public string Storage { get; set; }
    public string Website { get; set; }
    public string API { get; set; }
}

Tim, yapılandırma kaynağının özel olarak appsettings.json olması gerekmediğini belirtir. Bu appsettings.Development.json, secrets.json veya herhangi bir kombinasyon olabilir. Seçenekler deseni, uygulamada kayıtlı olan hangi yapılandırma sağlayıcısı okunursa okunsun onu okumak için kullanılır ve POCO üzerindeki özellik adları, JSON anahtarlarına geleneksel olarak eşleşir.

Program.cs İçinde Seçenekleri Kaydetme

[2:25 - 3:15] bağımlılık enjeksiyonuna yapılandırmayı bağlamak Program.cs içinde iki yöntem çağrısı alır:

// Register CloudInfoOptions bound to the "CloudInfo" section
builder.Services.AddOptions<CloudInfoOptions>()
    .BindConfiguration("CloudInfo");
// Register CloudInfoOptions bound to the "CloudInfo" section
builder.Services.AddOptions<CloudInfoOptions>()
    .BindConfiguration("CloudInfo");

AddOptions<t>() türü DI ile kaydeder. BindConfiguration("CloudInfo") yapılandırmanın hangi bölümünün eşleneceğini çerçeveye bildirir. "CloudInfo" dizesi appsettings.json içindeki JSON anahtarına karşılık gelir. Bölüm adı ve sınıf adı eşleşmezse, çerçeve doğru verileri bulmak için dize argümani kullanır.

IOptions: Singleton Yaklaşımı

[3:15 - 5:18] Kayıt tamamlandıktan sonra, Tim IOptions<CloudInfoOptions> kullanarak yapılandırmayı bir Blazor sayfasına enjekte eder:

@inject IOptions<CloudInfoOptions> CloudConfig

@code {
    protected override void OnInitialized()
    {
        var options = CloudConfig.Value;
        // options.Storage, options.Website, options.API are available
    }
}
@inject IOptions<CloudInfoOptions> CloudConfig

@code {
    protected override void OnInitialized()
    {
        var options = CloudConfig.Value;
        // options.Storage, options.Website, options.API are available
    }
}

Kritik ayrıntı, IOptions<t>'nın tekil olarak kaydedilmiş olmasıdır. Yapılandırma değerleri, uygulama başladığında bir kez okunur ve işlemin ömrü boyunca önbelleğe alınır. Uygulama çalışırken appsettings.json'i değiştirirseniz, IOptions bu değişiklikleri yansıtmaz.

Çoğu uygulama için bu doğru seçimdir. Yapılandırma nadiren çalışma zamanında değişir ve singleton yaşam süresinin her istek için sıfır yükü vardır.

IOptionsSnapshot: Kapsamlı Yenileme

[5:18 - 6:55] Tim, scoped varyantını göstermek için IOptionsIOptionsSnapshot ile değiştirir:

@inject IOptionsSnapshot<CloudInfoOptions> CloudConfig
@inject IOptionsSnapshot<CloudInfoOptions> CloudConfig

IOptionsSnapshot<t>, her talep için yeni yapılandırma okur (scoped yaşam süresi). Uygulama çalışırken appsettings.json'yi değiştirirseniz, bir sonraki web talebi yeni değerleri alacaktır. Önceki istek kendi anlık görüntüsünü korur, bu yüzden isteğin ortasında bir tutarsızlık yoktur.

Bu, yapılandırma değişikliklerinin yeniden başlatmadan yürürlüğe girmesi gereken uygulamalar için faydalıdır; örneğin, özellik bayrakları değiştirmek, API uç noktalarını güncellemek veya depolama bağlantı dizelerini döndürmek gibi. Ödün, yapılandırmayı tekrar okumak için isteğe bağlı küçük bir maliyettir, ki bu çoğu iş yükü için önemsizdir.

IOptionsMonitor: Canlı Değişiklik Bildirimleri

[6:55 - 8:34] Üçüncü varyant, IOptionsMonitor<t>, anlık görüntü yeniden yükleme sürecinden daha ileri gider. Yapılandırma değişikliklerini etkin olarak izler ve değerler güncellendiğinde geri çağrıları tetikleyebilir:

@inject IOptionsMonitor<CloudInfoOptions> CloudConfig

@code {
    protected override void OnInitialized()
    {
        // Current values
        var current = CloudConfig.CurrentValue;

        // Register a callback for live changes
        CloudConfig.OnChange(updatedOptions =>
        {
            // React to configuration changes in real time
        });
    }
}
@inject IOptionsMonitor<CloudInfoOptions> CloudConfig

@code {
    protected override void OnInitialized()
    {
        // Current values
        var current = CloudConfig.CurrentValue;

        // Register a callback for live changes
        CloudConfig.OnChange(updatedOptions =>
        {
            // React to configuration changes in real time
        });
    }
}

IOptionsSnapshot yalnızca talepler arasında yenilense de, IOptionsMonitor uzun süreli bir işlem sırasında değişiklikleri algılayabilir. Tim, bunun en alakalı olduğu yerin arka plan servisleri, SignalR hub'ları veya tek bir HTTP istek süresinden daha uzun ömürlü bileşenler olduğunu belirtiyor.

Doğrulama Ekleme

[8:34 - 10:05] Tim'in değindiği son parça doğrulamadır. Seçenekler deseni, yapılandırmaya ilk erişildiğinde çalışacak çevrimiçi doğrulama kurallarını destekler:

builder.Services.AddOptions<CloudInfoOptions>()
    .BindConfiguration("CloudInfo")
    .Validate(opts =>
        !string.IsNullOrEmpty(opts.Storage) &&
        !string.IsNullOrEmpty(opts.Website) &&
        !string.IsNullOrEmpty(opts.API));
builder.Services.AddOptions<CloudInfoOptions>()
    .BindConfiguration("CloudInfo")
    .Validate(opts =>
        !string.IsNullOrEmpty(opts.Storage) &&
        !string.IsNullOrEmpty(opts.Website) &&
        !string.IsNullOrEmpty(opts.API));

Tim, uygulamayı başlatarak appsettings.json'dan Storage değerini kaldırarak hata durumunu gösterir. Sonuç, "CloudInfoOptions doğrulama hatası" şeklinde anlık, yönetilmeyen bir istisna: Eksik yapılandırma ile başlamayı reddeden uygulama, istediğiniz tam davranış. Başlangıçta eksik bir değeri keşfetmek, üretimde saat 2'de null referansla karşılaşmaktan çok daha iyidir.

Daha karmaşık doğrulama senaryoları için (özellikler arası kontroller, koşullu kurallar), birden fazla .Validate() çağrısı zincirleyebilir veya IValidateOptions<t>'i özel bir doğrulama sınıfı olarak uygulayabilirsiniz.

Kapanış: Üç Arayüz, Bir Desen

[10:05 - 10:10] Seçenekler deseni, yapılandırma depolama ve tüketimi arasında temiz bir ayrım sağlar. IOptions, yapılandırmanın statik olduğu kullanım durumlarının çoğunu kapsar. IOptionsSnapshot, talepler arasında değişiklikleri almak zorunda kalan uygulamaları ele alır. IOptionsMonitor, yapılandırma güncellemelerinin gerçek zamanlı farkındalığını gerektiren uzun süre çalışan bileşenlere hizmet eder. Ve doğrulama, gereken değerler eksildiğinde uygulamanızın yüksek sesle başarısız olmasını sağlar.

Sonuç

[10:10 - 10:15] Özetlemek gerekirse: yapılandırmanızı AddOptions<t>().BindConfiguration("SectionName") ile Program.cs içinde kaydedin, yeniden yükleme gereksinimlerinize bağlı olarak üç arayüzden (IOptions, IOptionsSnapshot veya IOptionsMonitor) birini enjekte edin ve başlangıçta yerine çalışma zamanında eksik değerleri yakalamak için .Validate() ekleyin.

Desen, Blazor, ASP.NET Core, konsol uygulamaları, işçi servisleri içindeki herhangi bir .NET proje türünde çalışır. Kayıt her yerde aynıdır.

Örnek İpucu: Hangi arayüzü kullanmanız gerektiğinden emin değilseniz, IOptions<t> ile başlayın. En basitdir, her istek için sıfır yükü vardır ve yapılandırmanın başlatma sırasında ayarlandığı ve değişmediği çoğu durumu kapsar. Yalnızca çalışma zamanı yeniden yükleme için somut bir ihtiyaç duyduğunuzda IOptionsSnapshot veya IOptionsMonitor'e geçin.

Tam videoyu izleyin YouTube Kanalında ve C# yapılandırma desenleri hakkında daha fazla bilgi edinin.

Hero Worlddot related to C#'ta Seçenekler Deseni
Hero Affiliate related to C#'ta Seçenekler Deseni

Sevdiğiniz Şeyleri Paylaşarak Daha Fazla Kazanın

.NET, C#, Java, Python veya Node.js ile çalışan geliştiriciler için içerik oluşturuyor musunuz? Uzmanlığınızı ek gelire dönüştürün!

Iron Destek Ekibi

Haftada 5 gün, 24 saat çevrimiçiyiz.
Sohbet
E-posta
Beni Ara