AppSettings: 6 Formas de Ler o Config no ASP.NET CORE 3.0

Disponível também em inglês

Conheça 6 formas de acessar as configurações do arquivo AppSettings.JSON de uma aplicação ASP.NET CORE 3.0.

AppSettings: 6 Formas de Ler o Arquivo no ASP.NET CORE 3.0

Com o ASP.NET CORE, o arquivo WEB.CONFIG foi praticamente abolido. A não ser em casos que você precise hospedar uma aplicação .NET CORE no IIS.

Então, a bola da vez é o arquivo AppSettings.JSON, e existem diversas formas para acessar seu conteúdo.

Algumas informações importantes para quem está chegando agora. Se você é um desenvolvedor .NET mas nunca viu nada de .NET Core, sugiro você ler antes o artigo .NET Core para DesenvolvedoreS .NET.

JWT: Customizando o Identity no ASP.NET CORE 3.0

Imagine o arquivo de config dessa forma:

{
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft": "Warning",
            "Microsoft.Hosting.Lifetime": "Information"
        }
    },
    "MySettings": {
        "Log": true,
        "ConnectionStringId": "Default",
        "Parameters": {
            "IsProduction": true
        }
    },
  "AllowedHosts": "*"
}

E como caso de uso para esse artigo, vamos tentar acessar a propriedade IsProduction (bool).

Assim, as 6 formas de acessar essa propriedade, da mais complexa para a mais simples são:


#1 AppSettings – GetSection

A primeira forma consiste em usar o método GetSection da interface IConfiguration acessando nó pai/filho.

    [ApiController]
    [Route("[controller]")]
    public class Way1Controller : ControllerBase
    {
        private readonly IConfiguration _configuration;

        public Way1Controller(
            IConfiguration configuration)
        {
            _configuration = configuration;
        }

        [HttpGet]
        public bool Get()
        {
            return bool.Parse(_configuration.GetSection("MySettings").GetSection("Parameters").GetSection("IsProduction").Value); // here
        }
    }

Para chegar até IsProduction, é necessário antes acessar MySettings e depois Parameters.

E finalmente, acessar a propriedade Value, que retornará o valor String parametrizado, no caso “true“.

Como exemplo estamos retornando bool, então é preciso converter a string em bool.


#2 AppSettings – GetSection e GetValue

A segunda maneira, um pouquinho melhor, é utilizar do método GetValue passando a tipagem do valor que será convertido.

    [ApiController]
    [Route("[controller]")]
    public class Way2Controller : ControllerBase
    {
        private readonly IConfiguration _configuration;

        public Way2Controller(
            IConfiguration configuration)
        {
            _configuration = configuration;
        }

        [HttpGet]
        public bool Get()
        {
            return _configuration.GetSection("MySettings").GetSection("Parameters").GetValue<bool>("IsProduction"); // here
        }
    }

Usando bool para converter o valor de IsProduction é um pouco melhor que a primeira forma, mas ainda assim complexa e com muita repetição.


#3 AppSettings – GetValue inline

A terceira forma e mais elegante que as anteriores é fornecer todas as propriedades na ordem e separadas por dois pontos.

    [ApiController]
    [Route("[controller]")]
    public class Way3Controller : ControllerBase
    {
        private readonly IConfiguration _configuration;

        public Way3Controller(
            IConfiguration configuration)
        {
            _configuration = configuration;
        }

        [HttpGet]
        public bool Get()
        {
            return _configuration.GetValue<bool>("MySettings:Parameters:IsProduction"); // here
        }
    }

Há de concordar comigo que melhorou bastante comparando as formas anteriores.

Mas mesmo assim nós estamos explicitando strings no método GetValue, e injetando IConfiguration toda vez em cada Controller definitivamente não é uma boa solução.


#4 AppSettings – GetSection e Binding

A quarta maneira é fazer uma ligação “binding” entre a instância de uma classe com a section correspondente no AppSettings.JSON, no caso MySettings.

Antes de tudo então vamos criar uma classe MySettingsConfiguration e criar as mesmas propriedades com os mesmos nomes que estão no arquivo de configuração.

    public sealed class MySettingsConfiguration
    {
        public bool Log { get; set; }
        public string ConnectionStringId { get; set; }
        public Parameters Parameters { get; set; }
    }

    public sealed class Parameters
    {
        public bool IsProduction { get; set; }
    }

Então, agora é fazer o binding da tag MySettings com uma instância da classe de MySettingsConfiguration.

    [ApiController]
    [Route("[controller]")]
    public class Way4Controller : ControllerBase
    {
        private readonly MySettingsConfiguration _settings;

        public Way4Controller(
            IConfiguration configuration)
        {
            _settings = new MySettingsConfiguration();
            configuration.GetSection("MySettings").Bind(_settings);
        }

        [HttpGet]
        public bool Get()
        {
            return _settings?.Parameters?.IsProduction ?? false;
        }
    }

Ainda assim há muita informação explícita, como o nome usando em GetSection, injeção de dependência de IConfiguration e ainda instância da classe MySettingsConfiguration.


#5 AppSettings – IOptions

A penúltima forma para acessar o arquivo AppSettings.JSON é usar a interface IOptions tipando com a classe MySettingsConfiguration criada anteriormente.

    [ApiController]
    [Route("[controller]")]
    public class Way5Controller : ControllerBase
    {
        private readonly IOptions<MySettingsConfiguration> _configuration;

        public Way5Controller(
             IOptions<MySettingsConfiguration> configuration)
        {
            _configuration = configuration;
        }

        [HttpGet]
        public bool Get()
        {
            return _configuration.Value?.Parameters?.IsProduction ?? false;
        }
    }

Com a inteface IOptions ficou bem mais fácil, agora basta acessar as propriedades da instância MySettingsConfiguration dentro da propriedade Value.

Mas, para usar essa forma é necessário uma pequena configuração no arquivo Startup.cs.

        public void ConfigureServices(
            IServiceCollection services)
        {
            // Way 5
            services.Configure<MySettingsConfiguration>(Configuration.GetSection("MySettings"));

            services.AddControllers();
        }

Essa maneira com certeza é melhor que as anteriores, mas ainda explicitamos uma interface interna do ASP.NET CORE, no caso IOptions.

Seria interessante que os controllers e classes de negócio ficassem distintas, sem referências a classes/interfaces internas do .NET CORE.

Assim chegamos a sexta forma, a minha preferida.


#6 AppSettings – PRE-Binding

Simplesmente injete via construtor, a classe MySettingsConfiguration criada anteriomente.

    [ApiController]
    [Route("[controller]")]
    public class Way6Controller : ControllerBase
    {
        private readonly MySettingsConfiguration _configuration;

        public Way6Controller(
            MySettingsConfiguration configuration)
        {
            _configuration = configuration;
        }

        [HttpGet]
        public bool Get()
        {
            return _configuration.Parameters.IsProduction;
        }
    }

Essa forma é muito mais simples, tem todas as propriedades tipadas e não explicitamos nenhuma interface/classe interna do .NET CORE.

Para isso é necessário uma configuração no arquivo Startup.cs.

       public void ConfigureServices(
            IServiceCollection services)
        {
            // Way 6
            var mySettings = new MySettingsConfiguration();
            new ConfigureFromConfigurationOptions<MySettingsConfiguration>(Configuration.GetSection("MySettings")).Configure(mySettings);
            services.AddSingleton(mySettings);

            services.AddControllers();
        }

A configuração acima parece ser complexa, ainda mais se tivermos outras tags de configuração. Teriámos que ficar replicando esse bloco de código e não seria muito legal fazer isso.

Para facilitar, criei um Extension Methods que encapsula esse bloco de código, tornando seu uso muito mais simples.

       public void ConfigureServices(
            IServiceCollection services)
        {            
            // Way 6 extesion
            services.AddConfiguration<MySettingsConfiguration>(Configuration, "MySettings");

            services.AddControllers();
        }
    public static class ConfigurationExtension
    {
        public static void AddConfiguration<T>(
            this IServiceCollection services,
            IConfiguration configuration,
            string configurationTag = null)
            where T : class
        {
            if (string.IsNullOrEmpty(configurationTag))
            {
                configurationTag = typeof(T).Name;
            }

            var instance = Activator.CreateInstance<T>();
            new ConfigureFromConfigurationOptions<T>(configuration.GetSection(configurationTag)).Configure(instance);
            services.AddSingleton(instance);
        }
    }

Bom é isso aí.

Se você conheçe outras formas de acessar as configurações do arquivo AppSettings.JSON, compartilha aí que eu atualizo esse artigo.

Obrigado 🙂

Artigos sobre ASP.NET CORE:

Crie seu Framework em ASP.NET CORE 3 e Blazor
.NET Core para Desenvolvedores .NET
IIS: Como Hospedar Aplicação .NET Core em 10 Passos
Crie um Gerenciador de Arquivos do Zero em .NET Core e VueJS
JWT: Customizando o Identity no ASP.NET CORE 3.0
Benchmark: ASP.NET 4.8 vs ASP.NET CORE 3.0


Faça download completo do código fonte no github.
Sobre o Autor:
Trabalha como arquiteto de soluções e desenvolvedor, tem mais de 18 anos de experiência em desenvolvimento de software em diversas plataformas sendo mais de 16 anos somente para o mercado de seguros.
Revisado por:
Apaixonado por tecnologia e sempre disposto a encarar novos desafios, atualmente trabalho focado em aplicações web e mobile com a plataforma .NET, e me aventurando nas diversas linguagens, desafios e experiências que a área nos proporciona.


Paulistano, 21 anos apaixonado por tecnologia, trabalho com desenvolvimento de software atuando com .NET / Xamarin / AngularJS / ASP.NET CORE / MVC.