Pular para o conteúdo
.NETOptions pattern: IOptions, Snapshot e Monitor
Módulo 03Construindo a Web API

Options pattern: IOptions, Snapshot e Monitor

intermediario 40 min de leitura·Atualizado · .NET 9
Resumo

O Options Pattern liga seções de configuração a classes fortemente tipadas, injetadas via IOptions<T>, IOptionsSnapshot<T> e IOptionsMonitor<T> — cada uma com um comportamento de recarga diferente.

1. Objetivos de Aprendizagem#

  • Fazer binding de uma seção de configuração para uma classe.
  • Escolher entre IOptions, IOptionsSnapshot e IOptionsMonitor.
  • Validar opções na inicialização.

2. Pré-requisitos#

  • Configuração e ambientes (Módulo 16).

3. Conceito#

Em vez de espalhar Configuration["JwtSettings:Issuer"] (strings frágeis), você faz o bind de JwtSettings para uma classe. O porquê: tipagem forte, validação e testabilidade. As três interfaces diferem no ciclo de vida:

  • IOptions<T> — singleton, valor lido uma vez; não reflete mudanças em runtime.
  • IOptionsSnapshot<T> — scoped, recalculado por requisição; reflete mudanças de arquivo.
  • IOptionsMonitor<T> — singleton com notificação de mudança; útil em serviços singleton/background.

4. Mão na Massa#

4.1. Setup#

Sem pacotes extras (Microsoft.Extensions.Options).

4.2. Implementação Passo a Passo#

  1. Classe de opções:
C#
public class JwtSettings
{
    public const string Section = "JwtSettings";
    public string Issuer { get; set; } = default!;
    public string Audience { get; set; } = default!;
    public int ExpiresInMinutes { get; set; }
}
  1. Binding com validação:
C#
builder.Services.AddOptions<JwtSettings>()
    .Bind(builder.Configuration.GetSection(JwtSettings.Section))
    .ValidateDataAnnotations()
    .Validate(s => s.ExpiresInMinutes is > 0 and <= 60,
              "ExpiresInMinutes deve estar entre 1 e 60.")
    .ValidateOnStart();
  1. Consumo:
C#
public class TokenService
{
    private readonly JwtSettings _settings;
    public TokenService(IOptions<JwtSettings> options) => _settings = options.Value;
}

4.3. Executando#

ValidateOnStart() faz a aplicação falhar no boot se a configuração for inválida — muito melhor do que descobrir em runtime.

5. Exemplo Completo#

IOptionsSnapshot para refletir alterações de appsettings.json sem reiniciar:

C#
public class RelatorioService
{
    private readonly RelatorioOptions _opts;
    public RelatorioService(IOptionsSnapshot<RelatorioOptions> snap) => _opts = snap.Value;
}

6. Boas Práticas e Armadilhas#

FaçaEvite
Usar classes de opções tipadasLer Configuration["a:b:c"] espalhado no código
Validar com ValidateOnStartDescobrir config inválida só em produção
Escolher a interface pelo ciclo de vida corretoInjetar IOptionsSnapshot em um singleton
Atenção

não injete IOptionsSnapshot<T> (scoped) em um serviço singleton — gera captive dependency. Em singletons/background services, use IOptionsMonitor<T>.

7. Segurança e Produção#

  • Segredos (chaves, senhas) não pertencem ao appsettings.json; combine o Options Pattern com user-secrets (dev) e variáveis de ambiente/secret store (prod).
  • ValidateOnStart evita subir com configuração de segurança incompleta.

8. Exercícios#

  • Fácil: faça o bind de JwtSettings e injete via IOptions.
  • Médio: adicione validação Data Annotations ([Required], [Range]) às opções.
  • Desafio: use IOptionsMonitor num background service e reaja a mudanças de config.

9. Resumo#

O Options Pattern liga configuração a classes tipadas e validadas. IOptions/Snapshot/Monitor diferem no ciclo de vida e recarga — escolha conforme o consumidor. Segredos ficam fora do appsettings.

10. Próximos Passos#

Módulo 42: documentação da API com Swagger/OpenAPI.

11. Referências#

16-07 — Options pattern: IOptions, Snapshot e Monitor | Curso ASP.NET Core