DEV Community

Cover image for Using Options Pattern in ASP.NET Core
Spyros Ponaris
Spyros Ponaris

Posted on

3

Using Options Pattern in ASP.NET Core

In ASP.NET Core, the Options Pattern provides a clean way to manage configuration settings by binding them to strongly-typed objects. This allows for easy dependency injection and centralized management of application settings.

Example Configuration

Below is an example of an appsettings.json file containing SMTP configuration settings:

{
  "SmtpConfiguration": {
    "Domain": "smtp.gmail.com",
    "Port": 465
  }
}
Enter fullscreen mode Exit fullscreen mode

Defining the Configuration Object

Create a SmtpConfiguration class to represent these settings:

public record class SmtpConfiguration
{
    public string Domain { get; init; }
    public int Port { get; init; }
}
Enter fullscreen mode Exit fullscreen mode

Binding Configuration to the Object

To bind the configuration from appsettings.json to the SmtpConfiguration object, register it in the dependency injection system in Program.cs:

var builder = WebApplication.CreateBuilder(args);
builder.Services.Configure<SmtpConfiguration>(builder.Configuration.GetSection("SmtpConfiguration"));
Enter fullscreen mode Exit fullscreen mode

Using the Configuration in a Controller

The configuration can then be injected into a controller or service using IOptions:

public class DemoController : Controller
{
    private readonly SmtpConfiguration _smtpConfiguration;

    public DemoController(IOptions<SmtpConfiguration> smtpConfigurationOptions)
    {
        _smtpConfiguration = smtpConfigurationOptions.Value;
    }

    public IActionResult Index()
    {
        return Ok(new { _smtpConfiguration.Domain, _smtpConfiguration.Port });
    }
}
Enter fullscreen mode Exit fullscreen mode

This is the simplest way to use the Options Pattern in ASP.NET Core.

*Using Options Pattern with Middleware : *

The Options Pattern can also be used with class-based middleware. Below is an example:

public class LocationMiddleware
{
    private RequestDelegate next;
    private MessageOptions options;

    public LocationMiddleware(RequestDelegate nextDelegate, IOptions<MessageOptions> opts)
    {
        next = nextDelegate;
        options = opts.Value;
    }

    public async Task Invoke(HttpContext context)
    {
        if (context.Request.Path == "/location")
        {
            await context.Response.WriteAsync($"{options.CityName}, {options.CountryName}");
        }
        else
        {
            await next(context);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

IOptions vs IOptionsSnapshot vs IOptionsMonitor

The Options Pattern provides different ways to access configuration, depending on the use case. Here is a comparison:

Image description

Examples:

Using IOptions

For static configuration that doesn't change during the application's lifetime:

public class DemoService
{
    private readonly SmtpConfiguration _config;

    public DemoService(IOptions<SmtpConfiguration> options)
    {
        _config = options.Value;
    }

    public void PrintConfig()
    {
        Console.WriteLine(_config.Domain);
    }
}
Enter fullscreen mode Exit fullscreen mode

Using IOptionsSnapshot

For settings that change per request, typically in scoped services:

public class DemoService
{
    private readonly SmtpConfiguration _config;

    public DemoService(IOptionsSnapshot<SmtpConfiguration> optionsSnapshot)
    {
        _config = optionsSnapshot.Value;
    }

    public void PrintConfig()
    {
        Console.WriteLine(_config.Domain);
    }
}
Enter fullscreen mode Exit fullscreen mode

*Using IOptionsMonitor
*

For real-time updates to configuration settings:

public class DemoService
{
    private readonly IOptionsMonitor<SmtpConfiguration> _optionsMonitor;

    public DemoService(IOptionsMonitor<SmtpConfiguration> optionsMonitor)
    {
        _optionsMonitor = optionsMonitor;
    }

    public void PrintConfig()
    {
        var config = _optionsMonitor.CurrentValue;
        Console.WriteLine(config.Domain);
    }
}
Enter fullscreen mode Exit fullscreen mode

Key Notes:

  1. IOptions is simple to use and sufficient for most static configuration scenarios.

  2. IOptionsSnapshot is designed for scoped services and is ideal for configurations that change between requests.

  3. IOptionsMonitor is powerful for scenarios requiring live updates, such as reloading configuration files or environment variables at runtime.

References

Microsoft Documentation - Options Pattern: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-8.0

Microsoft Documentation - Configuration in ASP.NET Core: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration?view=aspnetcore-8.0

Microsoft Documentation - Dependency Injection in ASP.NET Core: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-8.0

Coding Clean, Reliable, and Safe REST APIs with ASP.NET Core 8: Develop Robust Minimal APIs with .NET 8 :
https://www.amazon.com/Coding-Clean-Reliable-Safe-ASP-NET/dp/1484299787

Summary

The Options Pattern is a powerful way to manage configuration in ASP.NET Core, enabling structured, type-safe access to settings. Combined with environment-specific configurations and development mode, you can create flexible and maintainable applications.

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

A simple "thank you" can illuminate someone's day. Express your appreciation in the comments section!

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay