Options pattern (IOptions)
ResumoO Options pattern mapeia uma seção de configuração para uma classe C# fortemente tipada, injetada via
IOptions<T>. Substitui strings mágicas por propriedades tipadas e validáveis.
1. Objetivos de Aprendizagem#
- Vincular (bind) uma seção a uma classe de options.
- Injetar options via
IOptions<T>. - Validar options na inicialização.
2. Pré-requisitos#
- IConfiguration (tópico 13.1) e DI (Módulo 12).
3. Conceito#
Em vez de ler config["Catalogo:TamanhoPaginaPadrao"] (string, sem tipo), você define uma classe CatalogoOptions e a vincula à seção. Depois injeta IOptions<CatalogoOptions> e acessa .Value. O porquê: tipagem forte, um único lugar para a forma da configuração, e validação centralizada.
Variações de acesso (aprofundadas no curso de Web API):
IOptions<T>— valor fixo (singleton).IOptionsSnapshot<T>— recarregado por requisição (scoped).IOptionsMonitor<T>— recebe atualizações em tempo real.
4. Mão na Massa#
4.1. Setup#
dotnet new console -n Catalog.Options
cd Catalog.Options
dotnet add package Microsoft.Extensions.Hosting
dotnet add package Microsoft.Extensions.Options
4.2. Implementação Passo a Passo#
- Classe de options e seção JSON:
public class CatalogoOptions
{
public const string Secao = "Catalogo";
public int TamanhoPaginaPadrao { get; set; }
public string MoedaPadrao { get; set; } = "BRL";
}
{ "Catalogo": { "TamanhoPaginaPadrao": 10, "MoedaPadrao": "BRL" } }
- Registrar o bind + validação:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
services.AddOptions<CatalogoOptions>()
.BindConfiguration(CatalogoOptions.Secao)
.Validate(o => o.TamanhoPaginaPadrao is > 0 and <= 50,
"TamanhoPaginaPadrao deve estar entre 1 e 50.")
.ValidateOnStart();
- Injetar e usar:
public class ServicoListagem
{
private readonly CatalogoOptions _opcoes;
public ServicoListagem(IOptions<CatalogoOptions> options) => _opcoes = options.Value;
public int Tamanho() => _opcoes.TamanhoPaginaPadrao;
}
4.3. Executando#
dotnet run
5. Exemplo Completo#
CatalogoOptions vinculada à seção "Catalogo", validada com ValidateOnStart(), é injetada em ServicoListagem via IOptions<T> — configuração tipada, validada e sem strings mágicas.
6. Boas Práticas e Armadilhas#
| Faça | Evite |
|---|---|
| Mapear seções para classes de options tipadas | Ler config["chave"] espalhado pelo código |
Validar com Validate + ValidateOnStart | Descobrir configuração inválida só em runtime tardio |
Injetar IOptions nos serviços | Injetar IConfiguration cru em toda parte |
Atenção
ValidateOnStart()faz a aplicação falhar na inicialização se a configuração estiver inválida — o que é desejável: melhor não subir do que rodar mal configurado.
7. Segurança e Produção#
- Validar options no start evita que a aplicação suba com valores perigosos (ex.: tamanho de página gigante que permite abuso ou configuração de segurança ausente).
8. Exercícios#
- Fácil: crie uma classe de options e vincule-a a uma seção.
- Médio: adicione uma regra de validação e teste com um valor inválido.
- Desafio: injete as options em dois serviços diferentes e confirme que compartilham os mesmos valores.
9. Resumo#
O Options pattern vincula seções de configuração a classes tipadas, injetadas via IOptions<T>, com validação (ValidateOnStart). Elimina strings mágicas e centraliza a forma da configuração.
10. Próximos Passos#
Encerramos configuração. A seguir, registrar o que acontece na aplicação: logging.
11. Referências#
- Microsoft Learn — Padrão de opções no .NET
- Microsoft Learn — Validação de options
- Microsoft Learn — Options pattern no ASP.NET Core