Como utilizar as configurações e opções de um aplicação .NET .
Tags: dotnet, csharp, codenewbie, braziliandevs
Published: 2022-04-11 23:00:48

Ter os conhecimentos nas configurações e opções é um conceito fundamental para as aplicações, exceto os aplicativos básicos.

## Os tópicos que serão apresentados
- Usar a configuração e como defini-la com arquivos JSON
- Acessar a configuração em runtime (tempo de execução).
- Entender sobre o padrão de opções que o .NET utiliza.
- Utilizar outros provedores de configuração, mantendo os segredos e chaves confidenciais seguras.

### O que é a classe Configuration?
- Prover configurações iniciais para sua aplicação.
- Ao mudar seus valores a aplicação não precisa ser recompilada.
- Pode ser definidas de várias origens diferentes.
- Acessamos em runtime, e podemos controlar o comportamento da aplicação.

> A classe Configuration ficam disponíveis através desse package: "Microsoft.Extensions.Configuration"

A estrutura de uma configuração é um dicionário com chave/valor, onde a chave sempre sera uma string, e valor um dado string ou um dicionário. Segue o exemplo:

```json
{
  "Secao1": {
    "ChaveA": "Valor da chave A",
    "ChaveB": "Valor da chave B"
  },
  "Secao2": {
    "SubSecao": {
      "ChaveA": "Valor da subsecção chave A"
    }
  }  
}
```
Para recuperar os valores podemos utilizar o padrão dessa maneira.
- Chave: "Secao1:ChaveA"
  - Output: "Valor da chave A""
- Chave: "Secao2:SubSecao:ChaveA" 
  - Output: "Valor da subsecção chave A"

Definindo as opções na prática, após criar um projeto .Net Web, vamos até o arquivo "appsettings.json"

![Local do arquivo "appsettings.json"](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y3pctda8djotxhy5j6aw.png)

> **Observação**: Percebe que temos dois arquivos appsettings, um ".json" e outro ".Development.json" eles seguem o padrão de carregamento que, caso seja informado algum valor na variável de lançamento ASPNETCORE_ENVIRONMENT, ele tentará ler o appsettings dessa variável e dará preferencia na busca, caso não consiga ira utilizar o "padrão", "appsettings.json".

Definiremos alguns valores de configuração dentro de um arquivo JSON, que será carregado quando nosso aplicativo for iniciado. Criei um controller, e fiz a injecção de dependencia da interface IConfiguration através do constructor, com ela temos o método GetValue<T>, e através dele recuperei o valor da nossa mensagem.

![Dois arquivo divididos, no lado esquerdo "AppSettingsController.cs" e no direito, "appsettings.json" e o navegador apresentando que a operação deu certo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eg9ypx3b160qp3rndzhp.png)

> **Observação**: Alterar os valores do "appsettings.json", não gera a necessidade de recompilar a aplicação.

Utilizando o método GetSection e pegando o valor de um campo utilizando novamente o GetValue<T>:

![Dois arquivo divididos, no lado esquerdo "AppSettingsController.cs" e no direito, "appsettings.json" e o navegador apresentando que a operação deu certo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rqlrlvg0yqvxxdajaf1b.png)

Vamos implementar algo um pouco mais complexo, nosso "feature flag" de demonstração, adicionei as seguinte opções na nossa configuração:

```json
{
  // ...código omitido
  "Features" : {
    "HelloWorldService": {
      "EnableService": false,
      "Messages": {
        "Default": "Hello World :)",
        "Disable": "Sorry, but I'm disabled ;("
      }
    }
  }
}
```

Criei uma interface para o serviço e duas implementação dessa interface:

```cs
public interface IHelloWorldService
{
    string SayHello();
}

public class HelloWorldService : IHelloWorldService
{
    private readonly IConfiguration _configuration;

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

    public string SayHello() => _configuration.GetValue<string>("Features:HelloWorldService:Messages:Default");
}

public class DisableHelloWorldService : IHelloWorldService
{
    private readonly IConfiguration _configuration;

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

    public string SayHello() => _configuration.GetValue<string>("Features:HelloWorldService:Messages:Disable");
}
```

Defini a resolução desse serviço na Program.cs:

```cs
// ...codigo omitido
if (builder.Configuration.GetValue<bool>("Features:HelloWorldService:EnableService"))
{
    builder.Services.TryAddSingleton<IHelloWorldService, HelloWorldService>();
}
else
{
    builder.Services.TryAddSingleton<IHelloWorldService, DisableHelloWorldService>();
}
```

### Referencias e créditos:
- Créditos da capa: https://unsplash.com/photos/KTpSVEcU0XU?utm_source=unsplash&utm_medium=referral&utm_content=creditShareLink