C# Academy · Aula

Options fortemente tipadas com IOptions

Associe seções de configuração a classes POCO usando IOptions , IOptionsSnapshot e IOptionsMonitor .

Aula 2 de 412 etapas

Options fortemente tipadas com IOptions é uma aula grátis de C# Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de C# Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de C# Academy inclui 4 aulas no total.

Por que usar opções fortemente tipadas?

Ler a configuração com IConfiguration["Key"] fornece cadeias de caracteres sem tipo. O padrão de opções mapeia seções de configuração para classes C#, oferecendo segurança em tempo de compilação, IntelliSense e suporte à validação.

Definição de uma classe de opções

Crie uma classe POCO simples cujos nomes de propriedades correspondam às suas chaves JSON. Por convenção, adicione uma constante estática SectionName para identificar a seção de configuração.

// Configuration class
public class JwtOptions
{
    public const string SectionName = "Jwt";

    public string SecretKey { get; set; } = string.Empty;
    public string Issuer    { get; set; } = string.Empty;
    public string Audience  { get; set; } = string.Empty;
    public int    ExpiryMinutes { get; set; } = 60;
}

// appsettings.json:
{
  "Jwt": {
    "SecretKey": "my-very-secret-key",
    "Issuer": "https://myapp.com",
    "Audience": "https://myapp.com/api",
    "ExpiryMinutes": 120
  }
}

Registro de opções

Chame Configure<T> para associar uma seção de configuração à classe de opções. Isso registra IOptions<T>, IOptionsSnapshot<T> e IOptionsMonitor<T> no DI.

// Registration
builder.Services.Configure<JwtOptions>(
    builder.Configuration.GetSection(JwtOptions.SectionName));

// Alternative shorthand:
builder.Services
    .AddOptions<JwtOptions>()
    .BindConfiguration(JwtOptions.SectionName);

// Consuming via IOptions<T>:
public class TokenService
{
    private readonly JwtOptions _opts;

    public TokenService(IOptions<JwtOptions> opts)
        => _opts = opts.Value;

    public string CreateToken()
        => $"Issuer={_opts.Issuer}, Exp={_opts.ExpiryMinutes}m";
}

IOptions vs IOptionsSnapshot vs IOptionsMonitor

Há três variantes, com diferentes tempos de vida e comportamentos de recarregamento. Escolha a mais adequada ao seu caso de uso.

// IOptions<T> — Singleton, reads config ONCE at startup
public class ApiClient(IOptions<ApiOptions> opts)
{
    private readonly ApiOptions _opts = opts.Value; // never changes
}

// IOptionsSnapshot<T> — Scoped, reloads per request
public class ReportService(IOptionsSnapshot<ReportOptions> opts)
{
    private readonly ReportOptions _opts = opts.Value; // fresh per request
}

// IOptionsMonitor<T> — Singleton, live updates + change notifications
public class FeatureService(IOptionsMonitor<FeatureFlags> monitor)
{
    public bool IsEnabled(string feature)
        => monitor.CurrentValue.EnabledFeatures.Contains(feature);
}

Validação de opções com atributos

Adicione atributos System.ComponentModel.DataAnnotations às propriedades das opções e chame ValidateDataAnnotations() para falhar imediatamente na inicialização caso a configuração seja inválida.

using System.ComponentModel.DataAnnotations;

public class SmtpOptions
{
    [Required]
    public string Host { get; set; } = string.Empty;

    [Range(1, 65535)]
    public int Port { get; set; } = 587;

    [Required, EmailAddress]
    public string FromAddress { get; set; } = string.Empty;
}

// Register with validation:
builder.Services
    .AddOptions<SmtpOptions>()
    .BindConfiguration("Smtp")
    .ValidateDataAnnotations()
    .ValidateOnStart(); // fail at startup, not first use

Validação personalizada com IValidateOptions

Para regras complexas entre propriedades, implemente IValidateOptions<T> para obter uma lógica de validação programática completa.

public class JwtOptionsValidator : IValidateOptions<JwtOptions>
{
    public ValidateOptionsResult Validate(string? name, JwtOptions opts)
    {
        var errors = new List<string>();

        if (string.IsNullOrWhiteSpace(opts.SecretKey))
            errors.Add("SecretKey must not be empty");

        if (opts.SecretKey.Length < 32)
            errors.Add("SecretKey must be at least 32 characters");

        if (opts.ExpiryMinutes <= 0)
            errors.Add("ExpiryMinutes must be positive");

        return errors.Any()
            ? ValidateOptionsResult.Fail(errors)
            : ValidateOptionsResult.Success;
    }
}

builder.Services.AddSingleton<IValidateOptions<JwtOptions>, JwtOptionsValidator>();

Configuração posterior

PostConfigure é executado depois de todas as chamadas a Configure e permite substituir ou derivar valores — útil para propriedades calculadas ou ajustes específicos do ambiente.

builder.Services.Configure<CacheOptions>(
    builder.Configuration.GetSection("Cache"));

// Override in test environment:
builder.Services.PostConfigure<CacheOptions>(opts =>
{
    if (builder.Environment.IsEnvironment("Testing"))
    {
        opts.AbsoluteExpirationMinutes = 1; // very short in tests
        opts.UseDistributedCache = false;   // use in-memory cache
    }
});

// PostConfigure always runs LAST, even after AddOptions validators

Opções nomeadas

Quando você precisa de várias instâncias do mesmo tipo de opções (por exemplo, dois servidores SMTP), use opções nomeadas para diferenciá-las.

// Register named options:
builder.Services.Configure<SmtpOptions>("Primary",
    builder.Configuration.GetSection("Smtp:Primary"));
builder.Services.Configure<SmtpOptions>("Backup",
    builder.Configuration.GetSection("Smtp:Backup"));

// Consume with IOptionsMonitor (supports named options):
public class EmailSender
{
    private readonly SmtpOptions _primary;
    private readonly SmtpOptions _backup;

    public EmailSender(IOptionsMonitor<SmtpOptions> monitor)
    {
        _primary = monitor.Get("Primary");
        _backup  = monitor.Get("Backup");
    }
}

Atalho BindConfiguration

A cadeia AddOptions().BindConfiguration() é a forma moderna e fluente de registrar, associar, validar e falhar imediatamente, tudo em uma única expressão.

// Full registration chain:
builder.Services
    .AddOptions<DatabaseOptions>()
    .BindConfiguration("Database")          // bind section
    .ValidateDataAnnotations()               // attribute validation
    .Validate(opts =>                        // custom rule
        opts.MaxPoolSize >= opts.MinPoolSize,
        "MaxPoolSize must be >= MinPoolSize")
    .ValidateOnStart();                      // fail at startup

// Shorthand for simple cases:
builder.Services.AddOptions<AppOptions>()
    .BindConfiguration(AppOptions.SectionName)
    .ValidateOnStart();

Exemplo do mundo real: opções de sinalizadores de funcionalidade

Uma configuração completa de opções de sinalizadores de funcionalidade com suporte a recarregamento, permitindo alterar alternâncias no appsettings sem uma nova implantação.

public class FeatureFlags
{
    public bool EnableNewCheckout  { get; set; }
    public bool EnableAISearch     { get; set; }
    public bool EnableBetaDashboard { get; set; }
}

// appsettings.json:
// { "FeatureFlags": { "EnableNewCheckout": true, ... } }

builder.Services
    .AddOptions<FeatureFlags>()
    .BindConfiguration("FeatureFlags")
    .ValidateOnStart();

// In a controller or service:
public class CheckoutController : ControllerBase
{
    private readonly FeatureFlags _flags;

    public CheckoutController(IOptionsMonitor<FeatureFlags> m)
        => _flags = m.CurrentValue;

    [HttpGet("/checkout")]
    public IActionResult Index() =>
        _flags.EnableNewCheckout
            ? Ok("new checkout")
            : Ok("legacy checkout");
}

Verificação rápida

Qual variante de IOptions você deve usar em um serviço de instância única que precisa refletir alterações de configuração em tempo real?

Recapitulação: opções fortemente tipadas com IOptions

Principais conclusões:

  • O padrão de opções associa seções de configuração a POCOs por meio de Configure<T> ou AddOptions<T>().BindConfiguration()
  • IOptions<T>: instância única, lê uma vez na inicialização
  • IOptionsSnapshot<T>: com escopo, recarrega a cada solicitação — não o injete em serviços de instância única
  • IOptionsMonitor<T>: seguro para serviços de instância única, com CurrentValue + OnChange em tempo real
  • Valide com DataAnnotations + ValidateDataAnnotations() + ValidateOnStart()
  • Use opções nomeadas para várias instâncias do mesmo tipo
Grátis para começar

Aprenda C# com um tutor de IA — grátis

Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.

Cursos
93
Aulas
346

Perguntas Frequentes

A aula “Options fortemente tipadas com IOptions” é grátis?

Sim — o texto completo de “Options fortemente tipadas com IOptions” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de C# Academy, atualize para CoddyKit PRO. O curso de C# Academy inclui 4 aulas no total.

O que vou aprender em “Options fortemente tipadas com IOptions”?

Associe seções de configuração a classes POCO usando IOptions , IOptionsSnapshot e IOptionsMonitor . Você pratica C# Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar C# Academy?

Nenhuma experiência prévia é necessária. C# Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.

Quanto tempo leva a aula “Options fortemente tipadas com IOptions”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de C# Academy?

Sim. Cada aula de C# Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Fontes e provedores de configuração
  2. Options fortemente tipadas com IOptions
  3. Validação de Options e Options nomeadas
  4. Gerenciamento de segredos
← Voltar para C# Academy