Pular para o conteúdo
.NETProgram.cs, serviços e métodos de extensão
Módulo 03Construindo a Web API

Program.cs, serviços e métodos de extensão

iniciante 20 min de leitura·Atualizado · .NET 9
Resumo

O Program.cs é o ponto de entrada e o lugar onde registramos serviços (no contêiner de DI) e montamos o pipeline HTTP. Para não deixá-lo gigante, extraímos os registros para métodos de extensão sobre IServiceCollection.

1. Objetivos de Aprendizagem#

  • Entender as duas fases do Program.cs: registrar serviços e construir o pipeline.
  • Registrar serviços com os tempos de vida corretos (Singleton, Scoped, Transient).
  • Organizar a configuração em métodos de extensão reutilizáveis.

2. Pré-requisitos#

  • Projeto Catalog.Api criado (tópico 16.1).

3. Conceito#

Desde o .NET 6, o Program.cs usa top-level statements e o WebApplicationBuilder. Há duas fases claras:

  1. Antes de builder.Build() — você adiciona serviços ao builder.Services (o contêiner de DI).
  2. Depois de builder.Build() — você configura o pipeline de middleware do app e chama app.Run().

O porquê dos métodos de extensão: conforme o projeto cresce, o Program.cs acumula dezenas de linhas de registro. Extrair isso para ServiceExtensions melhora legibilidade, testabilidade e reuso — um princípio direto de separação de responsabilidades.

4. Mão na Massa#

4.1. Setup#

Nenhum pacote novo. Vamos apenas reorganizar o Program.cs.

4.2. Implementação Passo a Passo#

  1. Crie a pasta Extensions/ e o arquivo ServiceExtensions.cs:
C#
namespace Catalog.Api.Extensions;

public static class ServiceExtensions
{
    public static IServiceCollection ConfigureControllers(this IServiceCollection services)
    {
        services.AddControllers();
        return services;
    }
}
  1. Registre serviços com o tempo de vida adequado. A regra prática:
  • AddSingleton — uma instância para toda a aplicação (ex.: cache em memória, configuração imutável).
  • AddScoped — uma instância por requisição HTTP (ex.: DbContext, repositórios).
  • AddTransient — uma nova instância a cada resolução (serviços leves e sem estado).
  1. Consuma a extensão no Program.cs (veja o Exemplo Completo).

4.3. Executando#

Shell
dotnet run

A aplicação sobe normalmente; a diferença está na organização do código, não no comportamento.

5. Exemplo Completo#

Program.cs:

C#
using Catalog.Api.Extensions;

var builder = WebApplication.CreateBuilder(args);

// Fase 1: registro de serviços
builder.Services.ConfigureControllers();

var app = builder.Build();

// Fase 2: pipeline HTTP
if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

app.Run();

6. Boas Práticas e Armadilhas#

FaçaEvite
Extrair registros para métodos de extensão coesosUm Program.cs com 200 linhas de registro
Escolher o tempo de vida certo (DbContext é Scoped)Injetar um serviço Scoped dentro de um Singleton (captured dependency)
Retornar IServiceCollection para encadear chamadasMétodos de extensão que não compõem
Atenção

injetar um serviço Scoped (como DbContext) dentro de um Singleton gera a captive dependency — o serviço scoped vive além da requisição e causa bugs difíceis. O .NET detecta muitos desses casos no startup quando ValidateScopes está ativo (padrão em Development).

7. Segurança e Produção#

  • Mantenha UseDeveloperExceptionPage apenas em Development; em produção use o middleware global de erros (Módulo 19).
  • A ordem do pipeline importa: UseAuthentication deve vir antes de UseAuthorization.

8. Exercícios#

  • Fácil: crie ConfigureCors como método de extensão e chame-o no Program.cs.
  • Médio: registre um serviço IDateTimeProvider como Singleton e injete-o num controller.
  • Desafio: provoque de propósito uma captive dependency e observe a exceção de validação de escopo no startup; explique a mensagem.

9. Resumo#

O Program.cs registra serviços e monta o pipeline. Métodos de extensão sobre IServiceCollection mantêm essa classe enxuta, e a escolha correta do tempo de vida evita bugs de ciclo de vida.

10. Próximos Passos#

A seguir configuramos CORS, integração com IIS e comportamento por ambiente.

11. Referências#

16-02 — Program.cs, serviços e métodos de extensão | Curso ASP.NET Core