I have looked this up at least twice this year. Maybe if I write about it, it will stick with me. If it doesn’t, well, at least I can look here.
Options Pattern
The Options pattern is a set of interfaces that allow you to read options into classes in your ASP.NET application. This allows you to configure options classes which are strongly typed with default values and attributes for option validation. It also removes most of the “magic strings” that can come along with reading configuration settings. I will do you all a favor and not regurgitate the documentation, but rather leave a link so you can read all about the pattern.
A Small Sample
Let’s assume I have a small class called HostSettings
to store my options:
public class HostSettings
{
public const string SectionName = "HostSettings";
public string Host { get; set; } = string.Empty;
public int Port { get; set; } = 5000;
}
And my appsettings.json
file looks like this:
{
"HostSettings": {
"Host": "http://0.0.0.0",
"Port": 5000
},
/// More settings here
}
Using Dependency Injection
For whatever reason, I always seem to remember how to configure options using the dependency injector. Assuming the above, adding options to the store looks something like this:
var builder = WebApplication.CreateBuilder(options);
builder.Services.Configure<HostSettings>(builder.Configuration.GetSection(HostSettings.SectionName));
From here, to get HostSettings
into your class, add an IOptions<HostSettings>
parameter to your class, and access the options using the IOptions.Value
implementation.
public class MyService
{
private readonly HostSettings _settings;
public MyService(IOptions<HostSettings) options)
{
_settings = options.Value;
}
}
Options without Dependency Injection
What I always, always forget about is how to get options without using the DI pattern. Every time I look it up, I have that “oh, that’s right” moment.
var hostSettings = new HostSettings();
builder.Configuration.GetSection(HostSEttings.SectionName).Bind(hostSettings);
Yup. That’s it. Seems silly that I forget that, but I do. Pretty much every time I need to use it.
A Note on SectionName
You may notice the SectionName
constant that I add to the class that holds the settings. This allows me to keep the name/location of the settings in the appsettings.json file within the class itself.
Since I only have a few classes which house these options, I load them manually. It would not be a stretch, however, to create a simple interface and use reflection to load options classes dynamically. It could even be encapsulated into a small package for distribution across applications… Perhaps an idea for an open source package.