Dış Yapılandırma Deposu düzeniExternal Configuration Store pattern

Yapılandırma bilgilerini uygulama dağıtım paketinden merkezi bir konuma taşıyın.Move configuration information out of the application deployment package to a centralized location. Bu model, yapılandırma verilerinin daha kolay yönetilmesi ve denetlenmesinin yanı sıra, yapılandırma verilerinin uygulamalar ve uygulama örnekleri arasında paylaşılması konusunda çeşitli avantajlar sağlayabilir.This can provide opportunities for easier management and control of configuration data, and for sharing configuration data across applications and application instances.

Bağlam ve sorunContext and problem

Çoğu uygulama çalışma zamanı ortamı, uygulama ile birlikte dağıtılan dosyaların barındırdığı yapılandırma bilgilerini içerir.The majority of application runtime environments include configuration information that's held in files deployed with the application. Bazı durumlarda, uygulama dağıtıldıktan sonra bu dosyaları düzenleyerek uygulamanın davranışını değiştirmek mümkündür.In some cases, it's possible to edit these files to change the application behavior after it's been deployed. Bununla birlikte, yapılandırmada değişiklik yapılması uygulamanın yeniden dağıtılmasını gerektirdiğinden, çoğu durumda kabul edilemez kapalı kalma sürelerine ve diğer yönetim yüklerine yol açar.However, changes to the configuration require the application be redeployed, often resulting in unacceptable downtime and other administrative overhead.

Yerel yapılandırma dosyaları da yapılandırmayı tek bir uygulamayla sınırlar, ancak bazen yapılandırma ayarlarının birden çok uygulamada ortak olması kullanışlı olur.Local configuration files also limit the configuration to a single application, but sometimes it would be useful to share configuration settings across multiple applications. Veritabanı bağlantı dizeleri, kullanıcı arabirimi tema bilgileri ya da ilgili bir uygulama kümesi tarafından kullanılan kuyruk ve depolama alanlarının URL’leri buna örnek olarak verilebilir.Examples include database connection strings, UI theme information, or the URLs of queues and storage used by a related set of applications.

Özellikle de bir bulutta barındırma senaryosunda, uygulamanın çalışan durumdaki birden çok örneğinde yerel yapılandırmalarda yapılan değişikliklerin yönetilmesi zordur.It's challenging to manage changes to local configurations across multiple running instances of the application, especially in a cloud-hosted scenario. Bu, güncelleştirme dağıtılırken örneklerin farklı yapılandırma ayarları kullanıyor olmasına yol açabilir.It can result in instances using different configuration settings while the update is being deployed.

Ayrıca, uygulama ve bileşenlerde yapılan güncelleştirmeler yapılandırma şemalarında değişiklik yapılmasını gerektirebilir.In addition, updates to applications and components might require changes to configuration schemas. Birçok yapılandırma sistemi, yapılandırma bilgilerinin farklı sürümlerini desteklemez.Many configuration systems don't support different versions of configuration information.

ÇözümSolution

Yapılandırma bilgilerini dış depolama alanında depolayın ve yapılandırma ayarlarının hızla okunup güncelleştirilmesi için kullanılabilecek bir arabirim sağlayın.Store the configuration information in external storage, and provide an interface that can be used to quickly and efficiently read and update configuration settings. Dış depolama türü, uygulamanın barındırma ve çalışma zamanı ortamına bağlıdır.The type of external store depends on the hosting and runtime environment of the application. Bulutta barındırma senaryolarında genellikle bulut tabanlı bir depolama hizmeti kullanılır, ancak barındırılan bir veritabanı veya başka bir sistem de kullanılabilir.In a cloud-hosted scenario it's typically a cloud-based storage service, but could be a hosted database or other system.

Yapılandırma bilgileri için seçtiğiniz yedekleme deposunun tutarlı ve kullanımı kolay erişim sağlayan bir arabirimi olmalıdır.The backing store you choose for configuration information should have an interface that provides consistent and easy-to-use access. Bilgileri doğru yazılmış ve yapılandırılmış bir biçimde kullanıma sunmalıdır.It should expose the information in a correctly typed and structured format. Uygulamanın yapılandırma verileri korumak için kullanıcıların erişimini yetkilendirmesi ve yapılandırmanın birden çok sürümünün (örneğin, geliştirme, hazırlama veya üretim aşamalarının her biri için birden çok sürüm) depolanmasına imkan sağlayabilecek kadar esnek olması da gerekebilir.The implementation might also need to authorize users’ access in order to protect configuration data, and be flexible enough to allow storage of multiple versions of the configuration (such as development, staging, or production, including multiple release versions of each one).

Birçok yerleşik yapılandırma sistemi, hızlı erişim sağlamak ve uygulama performansı üzerindeki etkiyi en aza indirmek için uygulama başlatıldığında verileri okur ve bellek üzerinde önbelleğe alır.Many built-in configuration systems read the data when the application starts up, and cache the data in memory to provide fast access and minimize the impact on application performance. Kullanılan yedekleme deposunun türüne ve bu deponun gecikme süresine bağlı olarak, dış yapılandırma deposunun içinde bir önbelleğe alma mekanizması uygulamak faydalı olabilir.Depending on the type of backing store used, and the latency of this store, it might be helpful to implement a caching mechanism within the external configuration store. Daha fazla bilgi için bkz. Önbelleğe Alma Kılavuzu.For more information, see the Caching Guidance. Şekilde, isteğe bağlı olarak yerel önbellek içeren Dış Yapılandırma Deposu düzenine genel bakış sunulmuştur.The figure illustrates an overview of the External Configuration Store pattern with optional local cache.

İsteğe bağlı olarak yerel önbellek içeren Dış Yapılandırma Deposu düzenine genel bakış

Sorunlar ve dikkat edilmesi gerekenlerIssues and considerations

Bu düzenin nasıl uygulanacağına karar verirken aşağıdaki noktaları göz önünde bulundurun:Consider the following points when deciding how to implement this pattern:

Kabul edilebilir düzeyde performans, yüksek kullanılabilirlik, sağlamlık sağlayan ve uygulama bakımı ile yönetimi sürecinin bir parçası olarak yedeklenebilecek bir yedekleme deposu seçin.Choose a backing store that offers acceptable performance, high availability, robustness, and can be backed up as part of the application maintenance and administration process. Bulutta barındırılan bir uygulamada bulut depolama mekanizması kullanılması genellikle bu gereksinimlerin karşılanması için iyi bir seçimdir.In a cloud-hosted application, using a cloud storage mechanism is usually a good choice to meet these requirements.

Yedekleme deposunun şemasını, içerebileceği bilgi türleri açısından esnek olacak şekilde tasarlayın.Design the schema of the backing store to allow flexibility in the types of information it can hold. Yazılan veriler, ayar koleksiyonları, ayarların birden çok sürümü ve şemayı kullanan uygulamaların gerektirdiği diğer tüm özellikler gibi yapılandırma gereksinimlerinin tamamını karşıladığından emin olun.Ensure that it provides for all configuration requirements such as typed data, collections of settings, multiple versions of settings, and any other features that the applications using it require. Şema, gereksinimler değiştikçe ek ayarları desteklemek üzere kolayca genişletilebilmelidir.The schema should be easy to extend to support additional settings as requirements change.

Yedekleme deposunun fiziksel özelliklerini, bunların yapılandırma bilgilerinin depolanmasıyla ilişkisini ve performans üzerindeki etkisini göz önünde bulundurun.Consider the physical capabilities of the backing store, how it relates to the way configuration information is stored, and the effects on performance. Örneğin, yapılandırma bilgilerini içeren bir XML belgesinin depolanması, yapılandırma arabiriminin veya uygulamanın ayrı ayrı ayarları okumak için belgeyi ayrıştırabilmesini gerektirir.For example, storing an XML document containing configuration information will require either the configuration interface or the application to parse the document in order to read individual settings. Bu, bir ayarın güncelleştirilmesini daha karmaşık hale getirse de ayarların önbelleğe alınması, yavaşlayan okuma performansının dengelenmesine yardımcı olabilir.It'll make updating a setting more complicated, though caching the settings can help to offset slower read performance.

Yapılandırma arabiriminin kapsamın denetlenmesine ve yapılandırma ayarlarının devralınmasına nasıl izin vereceğini göz önünde bulundurun.Consider how the configuration interface will permit control of the scope and inheritance of configuration settings. Örneğin, yapılandırma ayarları kapsamının kuruluş, uygulama ve makine düzeyinde belirlenmesi gerekebilir.For example, it might be a requirement to scope configuration settings at the organization, application, and the machine level. Erişim üzerindeki denetim için farklı kapsamların temsilci olarak atanmasını desteklemesi ve tek tek uygulamaların ayarları geçersiz kılmasını engellemesi ya da buna izin vermesi gerekebilir.It might need to support delegation of control over access to different scopes, and to prevent or allow individual applications to override settings.

Yapılandırma arabiriminin yapılandırma verilerini yazılan değerler, koleksiyonlar, anahtar/değer çiftleri veya özellik paketleri gibi gerekli biçimlerde kullanıma sunabildiğinden emin olun.Ensure that the configuration interface can expose the configuration data in the required formats such as typed values, collections, key/value pairs, or property bags.

Ayarların hata içermesi ya da yedekleme deposunda mevcut olmaması durumunda yapılandırma deposu arabiriminin nasıl davranacağını göz önünde bulundurun.Consider how the configuration store interface will behave when settings contain errors, or don't exist in the backing store. Varsayılan ayarların döndürülmesi ve hataların günlüğe kaydedilmesi uygun olabilir.It might be appropriate to return default settings and log errors. Ayrıca, yapılandırma ayarı anahtarlarının veya adlarının büyük/küçük harfe duyarlılığı, ikili verilerin depolanması ve işlenmesi ile null ya da boş değerlerin işlenme yolları gibi konuları göz önünde bulundurun.Also consider aspects such as the case sensitivity of configuration setting keys or names, the storage and handling of binary data, and the ways that null or empty values are handled.

Yapılandırma verilerinin yalnızca uygun kullanıcı ve uygulamalara erişim izin verecek şekilde nasıl korunacağını göz önünde bulundurun.Consider how to protect the configuration data to allow access to only the appropriate users and applications. Bu büyük olasılıkla yapılandırma deposu arabiriminin bir özelliğidir, ancak yedekleme deposundaki verilere uygun izin olmadan, doğrudan erişilememesini sağlamak da gereklidir.This is likely a feature of the configuration store interface, but it's also necessary to ensure that the data in the backing store can't be accessed directly without the appropriate permission. Yapılandırma verilerini okumak ve yazmak için gerekli izinler arasında katı bir ayrım olduğundan emin olun.Ensure strict separation between the permissions required to read and to write configuration data. Ayrıca, yapılandırma ayarlarının tümünü mü yoksa bir kısmını mı şifrelemeniz gerektiğini ve bunun yapılandırma deposu arabiriminde nasıl uygulanacağını göz önünde bulundurun.Also consider whether you need to encrypt some or all of the configuration settings, and how this'll be implemented in the configuration store interface.

Merkezi olarak depolan ve çalışma zamanı sırasında uygulama davranışını değiştiren yapılandırmalar kritik öneme sahiptir ve bunların uygulama kodunu dağıtmak için kullanılan mekanizmalarla dağıtılması, güncelleştirilmesi ve yönetilmesi gerekir.Centrally stored configurations, which change application behavior during runtime, are critically important and should be deployed, updated, and managed using the same mechanisms as deploying application code. Örneğin, birden fazla uygulamayı etkileyebilecek değişikliklerin bu yapılandırmayı kullanan tüm uygulamalar için uygun olduğundan emin olunması için bir tam test ve hazırlanmış dağıtım yaklaşımı kullanılarak gerçekleştirilmesi gerekir.For example, changes that can affect more than one application must be carried out using a full test and staged deployment approach to ensure that the change is appropriate for all applications that use this configuration. Bir yönetici, bir uygulamayı güncelleştirmek için bir ayarı düzenlerse, bu ayarı kullanan diğer uygulamalar bundan olumsuz etkilenebilir.If an administrator edits a setting to update one application, it could adversely impact other applications that use the same setting.

Bir uygulama yapılandırma bilgilerini önbelleğe alıyorsa, uygulama yapılandırması değiştiğinde bu uygulamanın uyarılması gerekir.If an application caches configuration information, the application needs to be alerted if the configuration changes. Önbelleğe alınan yapılandırma verileri için bir süre sonu ayarlayarak bu bilgilerin düzenli aralıklarla otomatik olarak yenilenmesi ve tüm değişikliklerin alınması (ve buna göre eylem gerçekleştirilmesi) sağlanabilir.It might be possible to implement an expiration policy over cached configuration data so that this information is automatically refreshed periodically and any changes picked up (and acted on).

Bu düzenin kullanılacağı durumlarWhen to use this pattern

Bu düzen aşağıdakiler için kullanışlıdır:This pattern is useful for:

  • Birden çok uygulama ve uygulama örneği arasında paylaşılan yapılandırma ayarları veya birden çok uygulama ve uygulama örneği arasında standart bir yapılandırmanın uygulanmasını gerektiren durumlar.Configuration settings that are shared between multiple applications and application instances, or where a standard configuration must be enforced across multiple applications and application instances.

  • Görüntüleri veya karmaşık veri türlerini depolama gibi gerekli yapılandırma ayarlarının tümünü desteklemeyen standart bir yapılandırma sistemi.A standard configuration system that doesn't support all of the required configuration settings, such as storing images or complex data types.

  • Örneğin uygulamaların merkezi olarak depolanan ayarların bazılarını veya tümünü geçersiz kılmasına izin vermek için bazı uygulama ayarlarına yönelik tamamlayıcı bir depo olarak.As a complementary store for some of the settings for applications, perhaps allowing applications to override some or all of the centrally-stored settings.

  • Birden çok uygulamanın yönetimini basitleştirmenin ve isteğe bağlı olarak yapılandırma deposuna yönelik bazı veya tüm erişim türlerinin günlüğe kaydedilmesi aracılığıyla yapılandırma ayarları kullanımının izlenmesinin bir yolu olarak.As a way to simplify administration of multiple applications, and optionally for monitoring use of configuration settings by logging some or all types of access to the configuration store.

ÖrnekExample

Microsoft Azure’da barındırılan bir uygulamada yapılandırma bilgilerini harici olarak depolamak için genellikle Azure Depolama tercih edilir.In a Microsoft Azure hosted application, a typical choice for storing configuration information externally is to use Azure Storage. Bu hizmet dayanıklıdır, yüksek performans sunar ve yüksek kullanılabilirlik sağlamak için otomatik yük devretme ile üç kez çoğaltılır.This is resilient, offers high performance, and is replicated three times with automatic failover to offer high availability. Azure Tablo depolama, değerler için esnek bir şemanın kullanılabileceği bir anahtar/değer deposu sağlar.Azure Table storage provides a key/value store with the ability to use a flexible schema for the values. Azure Blob depolama, tekil olarak adlandırılmış bloblarda her tür verinin depolanabildiği hiyerarşik, kapsayıcı tabanlı bir depolama sağlar.Azure Blob storage provides a hierarchical, container-based store that can hold any type of data in individually named blobs.

Aşağıdaki örnekte, yapılandırma bilgilerinin depolanması ve kullanıma sunulması için Blob depolama üzerine nasıl yapılandırma deposu uygulanabileceği gösterilmiştir.The following example shows how a configuration store can be implemented over Blob storage to store and expose configuration information. BlobSettingsStore sınıfı, Blob depolamayı yapılandırma bilgilerini barındıracak şekilde soyutlar ve aşağıdaki kodda gösterilen ISettingsStore arabirimini uygular.The BlobSettingsStore class abstracts Blob storage for holding configuration information, and implements the ISettingsStore interface shown in the following code.

Bu kod, GitHub’dan edinilebilecek ExternalConfigurationStore çözümündeki ExternalConfigurationStore.Cloud projesinde sağlanmıştır.This code is provided in the ExternalConfigurationStore.Cloud project in the ExternalConfigurationStore solution, available from GitHub.

public interface ISettingsStore
{
    Task<string> GetVersionAsync();

    Task<Dictionary<string, string>> FindAllAsync();
}

Bu arabirim, yapılandırma deposunda tutulan yapılandırma ayarlarını alma ve güncelleştirme metotlarını tanımlar ve herhangi bir yapılandırma ayarının yakın zamanda değiştirilmiş olup olmadığının algılanması için kullanılabilecek bir sürüm numarası içerir.This interface defines methods for retrieving and updating configuration settings held in the configuration store, and includes a version number that can be used to detect whether any configuration settings have been modified recently. BlobSettingsStore sınıfı, sürüm oluşturma işleminin uygulanması için blobun ETag özelliğini kullanır.The BlobSettingsStore class uses the ETag property of the blob to implement versioning. ETag özelliği, bloba her yazıldığında otomatik olarak güncelleştirilir.The ETag property is updated automatically each time the blob is written.

Bu basit çözüm, tasarımı gereği tüm yapılandırma ayarlarını yazılan değerler yerine dize değerleri olarak kullanıma sunar.By design, this simple solution exposes all configuration settings as string values rather than typed values.

ExternalConfigurationManager sınıfı, bir BlobSettingsStore nesnesinin çevresinde bir sarmalayıcı sağlar.The ExternalConfigurationManager class provides a wrapper around a BlobSettingsStore object. Bir uygulama, yapılandırma bilgilerini depolamak ve almak için bu sınıfı kullanabilir.An application can use this class to store and retrieve configuration information. Bu sınıf, IObservable arabiriminin uygulanması aracılığıyla yapılandırmada gerçekleştirilen tüm değişiklikleri ortaya çıkarmak için Microsoft’un Reactive Extensions kitaplığını kullanır.This class uses the Microsoft Reactive Extensions library to expose any changes made to the configuration through an implementation of the IObservable interface. Bir ayar SetAppSetting metodu çağrılarak değiştirilirse Changed olayı oluşturulur ve bu olayın tüm abonelerine bildirim gönderilir.If a setting is modified by calling the SetAppSetting method, the Changed event is raised and all subscribers to this event will be notified.

Hızlı erişim için tüm ayarların ExternalConfigurationManager sınıfı içindeki bir Dictionary nesnesinde de önbelleğe alındığını unutmayın.Note that all settings are also cached in a Dictionary object inside the ExternalConfigurationManager class for fast access. Bir yapılandırma ayarının alınması için kullanılan GetSetting yöntemi, önbellekten verileri okur.The GetSetting method used to retrieve a configuration setting reads the data from the cache. Bu ayar önbellekte bulunamazsa onun yerine BlobSettingsStore nesnesinden alınır.If the setting isn't found in the cache, it's retrieved from the BlobSettingsStore object instead.

GetSettings metodu, blob depolamadaki yapılandırma bilgilerinin değişip değişmediğini algılamak için CheckForConfigurationChanges metodunu çağırır.The GetSettings method invokes the CheckForConfigurationChanges method to detect whether the configuration information in blob storage has changed. Bunu, sürüm numarasını inceleyip ExternalConfigurationManager nesnesinin sahip olduğu geçerli sürüm numarasıyla karşılaştırarak gerçekleştirir.It does this by examining the version number and comparing it with the current version number held by the ExternalConfigurationManager object. Bir veya daha fazla değişiklik oluştuysa Changed olayı tetiklenir ve Dictionary nesnesinde önbelleğe alınmış yapılandırma ayarları yenilenir.If one or more changes have occurred, the Changed event is raised and the configuration settings cached in the Dictionary object are refreshed. Bu bir Edilgen Önbellek düzeni uygulamasıdır.This is an application of the Cache-Aside pattern.

Aşağıdaki kod örneğinde Changed olayı, GetSettings metodu ve CheckForConfigurationChanges metodunun nasıl uygulandığı gösterilmiştir:The following code sample shows how the Changed event, the GetSettings method, and the CheckForConfigurationChanges method are implemented:

public class ExternalConfigurationManager : IDisposable
{
  // An abstraction of the configuration store.
  private readonly ISettingsStore settings;
  private readonly ISubject<KeyValuePair<string, string>> changed;
  ...
  private readonly ReaderWriterLockSlim settingsCacheLock = new ReaderWriterLockSlim();
  private readonly SemaphoreSlim syncCacheSemaphore = new SemaphoreSlim(1);  
  ...
  private Dictionary<string, string> settingsCache;
  private string currentVersion;
  ...
  public ExternalConfigurationManager(ISettingsStore settings, ...)
  {
    this.settings = settings;
    ...
  }
  ...
  public IObservable<KeyValuePair<string, string>> Changed => this.changed.AsObservable();
  ...

  public string GetAppSetting(string key)
  {
    ...
    // Try to get the value from the settings cache.
    // If there's a cache miss, get the setting from the settings store and refresh the settings cache.

    string value;
    try
    {
        this.settingsCacheLock.EnterReadLock();

        this.settingsCache.TryGetValue(key, out value);
    }
    finally
    {
        this.settingsCacheLock.ExitReadLock();
    }

    return value;
  }
  ...
  private void CheckForConfigurationChanges()
  {
    try
    {
        // It is assumed that updates are infrequent.
        // To avoid race conditions in refreshing the cache, synchronize access to the in-memory cache.
        await this.syncCacheSemaphore.WaitAsync();

        var latestVersion = await this.settings.GetVersionAsync();

        // If the versions are the same, nothing has changed in the configuration.
        if (this.currentVersion == latestVersion) return;

        // Get the latest settings from the settings store and publish changes.
        var latestSettings = await this.settings.FindAllAsync();

        // Refresh the settings cache.
        try
        {
            this.settingsCacheLock.EnterWriteLock();

            if (this.settingsCache != null)
            {
                //Notify settings changed
                latestSettings.Except(this.settingsCache).ToList().ForEach(kv => this.changed.OnNext(kv));
            }
            this.settingsCache = latestSettings;
        }
        finally
        {
            this.settingsCacheLock.ExitWriteLock();
        }

        // Update the current version.
        this.currentVersion = latestVersion;
    }
    catch (Exception ex)
    {
        this.changed.OnError(ex);
    }
    finally
    {
        this.syncCacheSemaphore.Release();
    }
  }
}

ExternalConfigurationManager sınıfı Environment adlı bir özellik de sağlar.The ExternalConfigurationManager class also provides a property named Environment. Bu özellik, hazırlama ve üretim gibi farklı ortamlarda çalışan bir uygulama için değişkenlik gösteren yapılandırmaları destekler.This property supports varying configurations for an application running in different environments, such as staging and production.

Bir ExternalConfigurationManager nesnesi, herhangi bir değişiklik olup olmadığını öğrenmek amacıyla BlobSettingsStore nesnesini de düzenli aralıklarla sorgulayabilir.An ExternalConfigurationManager object can also query the BlobSettingsStore object periodically for any changes. Aşağıdaki kodda, StartMonitor metodu herhangi bir değişiklik olup olmadığını algılamak için belirli aralıklarla CheckForConfigurationChanges çağrısı yapar ve daha önce açıklandığı gibi Changed olayını tetikler.In the following code, the StartMonitor method calls CheckForConfigurationChanges at an interval to detect any changes and raise the Changed event, as described earlier.

public class ExternalConfigurationManager : IDisposable
{
  ...
  private readonly ISubject<KeyValuePair<string, string>> changed;
  private Dictionary<string, string> settingsCache;
  private readonly CancellationTokenSource cts = new CancellationTokenSource();
  private Task monitoringTask;
  private readonly TimeSpan interval;

  private readonly SemaphoreSlim timerSemaphore = new SemaphoreSlim(1);
  ...
  public ExternalConfigurationManager(string environment) : this(new BlobSettingsStore(environment), TimeSpan.FromSeconds(15), environment)
  {
  }
  
  public ExternalConfigurationManager(ISettingsStore settings, TimeSpan interval, string environment)
  {
      this.settings = settings;
      this.interval = interval;
      this.CheckForConfigurationChangesAsync().Wait();
      this.changed = new Subject<KeyValuePair<string, string>>();
      this.Environment = environment;
  }
  ...
  /// <summary>
  /// Check to see if the current instance is monitoring for changes
  /// </summary>
  public bool IsMonitoring => this.monitoringTask != null && !this.monitoringTask.IsCompleted;

  /// <summary>
  /// Start the background monitoring for configuration changes in the central store
  /// </summary>
  public void StartMonitor()
  {
      if (this.IsMonitoring)
          return;

      try
      {
          this.timerSemaphore.Wait();

          // Check again to make sure we are not already running.
          if (this.IsMonitoring)
              return;

          // Start running our task loop.
          this.monitoringTask = ConfigChangeMonitor();
      }
      finally
      {
          this.timerSemaphore.Release();
      }
  }

  /// <summary>
  /// Loop that monitors for configuration changes
  /// </summary>
  /// <returns></returns>
  public async Task ConfigChangeMonitor()
  {
      while (!cts.Token.IsCancellationRequested)
      {
          await this.CheckForConfigurationChangesAsync();
          await Task.Delay(this.interval, cts.Token);
      }
  }

  /// <summary>
  /// Stop monitoring for configuration changes
  /// </summary>
  public void StopMonitor()
  {
      try
      {
          this.timerSemaphore.Wait();

          // Signal the task to stop.
          this.cts.Cancel();

          // Wait for the loop to stop.
          this.monitoringTask.Wait();

          this.monitoringTask = null;
      }
      finally
      {
          this.timerSemaphore.Release();
      }
  }

  public void Dispose()
  {
      this.cts.Cancel();
  }
  ...
}

Aşağıda gösterilen ExternalConfiguration sınıfı tarafından ExternalConfigurationManager sınıfının tekil örnek biçiminde bir örneği oluşturulur.The ExternalConfigurationManager class is instantiated as a singleton instance by the ExternalConfiguration class shown below.

public static class ExternalConfiguration
{
    private static readonly Lazy<ExternalConfigurationManager> configuredInstance = new Lazy<ExternalConfigurationManager>(
        () =>
        {
            var environment = CloudConfigurationManager.GetSetting("environment");
            return new ExternalConfigurationManager(environment);
        });

    public static ExternalConfigurationManager Instance => configuredInstance.Value;
}

Aşağıdaki kod, ExternalConfigurationStore.Cloud projesindeki WorkerRole sınıfından alınmıştır.The following code is taken from the WorkerRole class in the ExternalConfigurationStore.Cloud project. Uygulamanın bir ayarı okumak için ExternalConfiguration sınıfını nasıl kullandığını gösterir.It shows how the application uses the ExternalConfiguration class to read a setting.

public override void Run()
{
  // Start monitoring configuration changes.
  ExternalConfiguration.Instance.StartMonitor();

  // Get a setting.
  var setting = ExternalConfiguration.Instance.GetAppSetting("setting1");
  Trace.TraceInformation("Worker Role: Get setting1, value: " + setting);

  this.completeEvent.WaitOne();
}

Yine WorkerRole sınıfından alınmış olan aşağıdaki kod, uygulamanın yapılandırma olaylarına nasıl abone olduğunu gösterir.The following code, also from the WorkerRole class, shows how the application subscribes to configuration events.

public override bool OnStart()
{
  ...
  // Subscribe to the event.
  ExternalConfiguration.Instance.Changed.Subscribe(
     m => Trace.TraceInformation("Configuration has changed. Key:{0} Value:{1}",
          m.Key, m.Value),
     ex => Trace.TraceError("Error detected: " + ex.Message));
  ...
}
  • Bu düzeni gösteren bir örnek GitHub’dan edinilebilir.A sample that demonstrates this pattern is available on GitHub.