QPANC - Parte 3 - ASP.NET - Registrando Serviços e Lendo Variáveis de Ambiente
Tags: quasar, postgres, aspnetcore, docker
Published: 2020-04-19 23:35:29

> **QPANC** são as iniciais de **Q**uasar **P**ostgreSQL **A**SP **N**ET **C**ore.

  * [Source](https://github.com/TobyMosque/qpanc)
  * [Introdução](https://dev.to/quasar-pt-br/arquiteturando-uma-aplicacao-com-quasar-postgresql-asp-net-core-e-docker-introducao-o7o)
  * [Parte I - ASP.NET - Inicializando os Projetos](https://dev.to/quasar-pt-br/qpanc-parte-1-asp-net-inicializando-os-projetos-lkm)
  * [Parte 2 - PostgreSQL](https://dev.to/quasar-pt-br/qpanc-parte-2-postgresql-51pb)
  * [Parte 3 - ASP.NET - Registrando Serviços e Lendo Variáveis de Ambiente](https://dev.to/quasar-pt-br/qpanc-parte-3-asp-net-registrando-servicos-e-lendo-variaveis-de-ambiente-3do2)
  * [Parte 4 - ASP.NET - Entity Framework e ASP.NET Core Identity](https://dev.to/quasar-pt-br/qpanc-parte-4-asp-net-entity-framework-e-asp-net-core-identity-40f9)
  * [Parte 5 - ASP.NET - Documentação Interativa com Swagger](https://dev.to/quasar-pt-br/qpanc-parte-5-asp-net-documentacao-interativa-com-swagger-4n0o)
  * [Parte 6 - ASP.NET - Regionalização](https://dev.to/quasar-pt-br/qpanc-parte-6-asp-net-regionalizacao-13p5)
  * [Parte 7 - ASP.NET - Autenticação e Autorização](https://dev.to/quasar-pt-br/qpanc-parte-7-asp-net-autenticacao-e-autorizacao-bpd)
  * [Parte 8 - ASP.NET - CORS](https://dev.to/quasar-pt-br/qpanc-parte-8-asp-net-cors-52dn)
  * [Parte 9 - Quasar - Criação e Configuração do Projeto](https://dev.to/quasar-pt-br/qpanc-parte-9-quasar-criacao-e-configuracao-do-projeto-5hbi)
  * [Parte 10 - Quasar - Configurações e Customizações](https://dev.to/quasar-pt-br/qpanc-parte-10-quasar-configuracoes-e-customizacoes-2i86)
  * [Parte 11 - Quasar - Componentes - Diferença entre SPA e SSR](https://dev.to/quasar-pt-br/qpanc-parte-11-quasar-componentes-diferenca-entre-spa-e-ssr-1a3c)
  * [Parte 12 - Quasar - Serviços](https://dev.to/quasar-pt-br/qpanc-parte-12-quasar-servicos-4e61)
  * [Parte 13 - Quasar - Regionalização e Stores](https://dev.to/quasar-pt-br/qpanc-parte-13-quasar-regionalizacao-e-stores-1kep)
  * [Parte 14 - Quasar - Consumindo a API](https://dev.to/quasar-pt-br/qpanc-parte-14-quasar-consumindo-a-api-fn6)
  * [Parte 15 - Quasar - Login](https://dev.to/quasar-pt-br/qpanc-parte-15-quasar-login-jc6)
  * [Parte 16 - Quasar - Áreas Protegidas](https://dev.to/quasar-pt-br/qpanc-parte-16-quasar-areas-protegidas-3jkn)
  * [Parte 17 - Quasar - Registro](https://dev.to/quasar-pt-br/qpanc-parte-17-quasar-registro-3b8c)
  * [Parte 18 - Docker - Maquina Virtual Linux](https://dev.to/quasar-pt-br/qpanc-parte-18-docker-maquina-virtual-linux-g5c)
  * [Parte 19 - Docker - Registro e Build](https://dev.to/quasar-pt-br/qpanc-parte-19-docker-registro-e-build-31i4)
  * [Parte 20 - Docker - Traefik e Publicação](https://dev.to/quasar-pt-br/qpanc-parte-20-docker-traefik-e-publicacao-3g3d)
  * [Demo Online](https://qpanc.tobiasmesquita.dev)

##6 Lendo variáveis de ambiente

###6.1 adicionando uma string de conexão as variáveis de ambiente

Primeiro, precisamos incluir nas nossas variaveis de ambiente, uma string de conexão, para tal, edite o `docker-compose.override.yml`:

```
version: '3.4'

services:
  qpanc.api:
    environment:
      - DEFAULT_CONNECTION=Server=qpanc.database;Port=5432;Database=postgres;User Id=postgres;Password=keepitsupersecret;
    ...
  qpanc.database:
    ...
```

###6.2 Definindo as demais interfaces

Agora precisaremos adicionar as demais interfaces à blibioteca `QPANC.Services.Abstract`, mas antes, precisaremos adicionar um pacote à blibioteca:

```
cd QPANC.Services.Abstract
dotnet add package Microsoft.Extensions.Configuration.Abstractions
dotnet add package System.ComponentModel.Annotations
```

então, crie as interfaces `IConfiguration`, `IAppSettings` e `IConnectionStrings`.:
```cs
using Microsoft.Extensions.Configuration;

namespace QPANC.Services.Abstract
{
    public interface IConfiguration
    {
        IConfigurationRoot Root { get; }
    }
}
```
```cs
namespace QPANC.Services.Abstract
{
    public interface IAppSettings
    {
        IConnectionStrings ConnectionString { get; }
    }
}
```
```cs
namespace QPANC.Services.Abstract
{
    public interface IConnectionStrings
    {
        string DefaultConnection { get; }
    }
}
```

A interface `IConfiguration` será responsável por ler as configurações, ela será uma dependência de todas as classes de Configuração, tais como à `IConnectionStrings`.

A interface `IAppSettings` será uma agregadora das classes de configuração.

Desta forma, qual nova interface utilizar para configurar a aplicação, terá uma estrutura similar à `IConnectionStrings`. sendo dependente da `IConfiguration` e sendo uma dependência para à `IAppSettings`.

###7.2 Implementando as interfaces

Agora, iremos voltar a nossa atenção para o projeto `QPANC.Services`, instale os seguintes pacotes nele:

```
cd QPANC.Services
dotnet add package Microsoft.AspNetCore.Hosting.Abstractions
dotnet add package Microsoft.Extensions.Configuration.Binder
dotnet add package Microsoft.Extensions.Configuration.EnvironmentVariables
dotnet add package Microsoft.Extensions.Configuration.Json
```

Agora iremos começar a implementar as nossas interfaces, para tal, crie as classes `Configuration`, `ConnectionStrings` e `AppSettings`.

```cs
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using IConfiguration = QPANC.Services.Abstract.IConfiguration;

namespace QPANC.Services
{
    public class Configuration : IConfiguration
    {
        public IConfigurationRoot Root { get; }

        public Configuration(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables();
            this.Root = builder.Build();
        }
    }
}
```
```cs
using Microsoft.Extensions.Configuration;
using QPANC.Services.Abstract;
using IConfiguration = QPANC.Services.Abstract.IConfiguration;

namespace QPANC.Services
{
    public class ConnectionStrings : IConnectionStrings
    {
        private IConfiguration _configuration;

        public ConnectionStrings(IConfiguration configuration)
        {
            this._configuration = configuration;
        }

        public string DefaultConnection { get { return this._configuration.Root.GetValue<string>("DEFAULT_CONNECTION"); } }
    }
}
```
```cs
using QPANC.Services.Abstract;

namespace QPANC.Services
{
    public class AppSettings : IAppSettings
    {
        public IConnectionStrings ConnectionString { get; }

        public AppSettings(IConnectionStrings connectionStrings)
        {
            this.ConnectionString = connectionStrings;
        }
    }
}
```

###6.3 Registrando os serviços

Agora que finalizamos a implementação dos serviços, iremos criar uma extensão para registrá-los, para tal, vá ao projeto `QPANC.Api`, crie a pasta `Extensions`, então crie a classe estática `ServiceCollectionExtensions`.

```cs
using Microsoft.Extensions.DependencyInjection;
using QPANC.Services;
using QPANC.Services.Abstract;

namespace QPANC.Api.Extensions
{
    public static class ServiceCollectionExtensions
    {
        public static void AddAppSettings(this IServiceCollection services)
        {
            services.AddSingleton<IConfiguration, Configuration>();
            services.AddSingleton<IConnectionStrings, ConnectionStrings>();
            // services.AddSingleton<IJwtBearer, JwtBearer>();
            services.AddSingleton<IAppSettings, AppSettings>();
        }
    }
}
```

agora, precisamos apenas chamar o método acima no `QPANC.Api.Startup`

```cs
...
using QPANC.Api.Extensions;

namespace QPANC.Api
{
    public class Startup
    {
        ...
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddAppSettings();
        }
        ...
    }
}
```

###6.4 testando os serviços

agora, para testar, injete o `IAppSettings` settings no método `Configure` do `Startup`

```cs
...
using QPANC.Api.Extensions;

namespace QPANC.Api
{
    public class Startup
    {
        ...
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IAppSettings settings)
        {
            Console.WriteLine(settings.ConnectionString.DefaultConnection);
            ...
        }
    }
}
```

caso coloque um breakpoint e execute o código, deverá ver algo como:

![Connection String Breakpoint](https://dev-to-uploads.s3.amazonaws.com/i/0qlj3jjjfarhvirqws66.png)