Objetivo

O propósito deste artigo é apresentar um mecanismo que viabilize a leitura de chaves de configuração “atualizadas” após a alteração do arquivo de configurações da aplicação (.exe.config).
Este mecanismo pode ser muito útil caso você tenha um sistema non-stop, como por exemplo um Windows Service, onde você não precisará reiniciar o serviço para que as novas configurações sejam reconhecidas pelo serviço.
O exemplo descrito ao longo deste post não se aplica ao ASP.NET, visto que por padrão, o IIS 6.0/7.0/7.5 cria um novo processo quando o web.config é alterado.

Solução

A solução consiste em criar um objeto FileSystemWatcher que receba uma notificação quando o arquivo de configurações for alterado. Segue abaixo o código-fonte de uma aplicação console:

class Program
{
    static void Main(string[] args)
    {
        /* Objeto FileSystemWatcher que sera notificado quando
         * o arquivo de configurações for alterado.
         */
        string filePath=System.Reflection.Assembly.GetExecutingAssembly().Location.Replace(”ConfigurationManagerCache.exe”, “”);
        System.IO.FileSystemWatcher watcher = new System.IO.FileSystemWatcher(filePath, “ConfigurationManagerCache.exe.config”);
        watcher.NotifyFilter = System.IO.NotifyFilters.LastAccess;
        watcher.Changed += new System.IO.FileSystemEventHandler(ConfigurationFileChange);
        watcher.EnableRaisingEvents = true;

        while (true)
        {
            System.Console.WriteLine(”Name={0}”, System.Configuration.ConfigurationManager.AppSettings[”Name”]);
            System.Console.WriteLine(”LocalDB={0}”, System.Configuration.ConfigurationManager.ConnectionStrings[”LocalDB”].ConnectionString);
            System.Console.WriteLine();
            System.Threading.Thread.Sleep(1000);
        }
    }

    static void ConfigurationFileChange(object sender, System.IO.FileSystemEventArgs e)
    {
        /* Este sleep e necessario para que o usuario tenha ate 5 segundos
         * para salvar e fechar o arquivo antes da tentativa de leitura
         * pelo programa o que causara uma excecao caso o arquivo ainda
         * esteja aberto.
         */
        System.Threading.Thread.Sleep(5000);

        //Faz SOMENTE o refresh das secoes connectionStrings e appSettings
        System.Configuration.ConfigurationManager.RefreshSection(”connectionStrings”);
        System.Configuration.ConfigurationManager.RefreshSection(”appSettings”);

        System.Console.WriteLine();
        System.Console.WriteLine(”– Sections ‘connectionStrings’ and ‘appSettings’ refreshed. –”);
        System.Console.WriteLine();
    }
}