Project – OptionsConfiguration – Options, Settings, and Configuration

Now that we have covered basic usage scenarios, let’s attack some more advanced possibilities, such as creating types to configure, initialize, and validate our options.We start by configuring options which happen in two phases:

  1. The configuration phase.
  2. The post-configuration phase.

In a nutshell, the post-configuration phase happens later in the process. This is a good place to enforce that some values are configured a certain way or to override configuration, for example, in integration tests.To configure an options class, we have many options, starting with the following interfaces:

InterfaceDescription
IConfigureOptions<TOptions>Configure the default TOptions type.
IConfigureNamedOptions<TOptions>Configure the default and named TOptions type.
IPostConfigureOptions<TOptions>Configure the default and named TOptions type during the post-configuration phase.

 Table 9.2: interfaces to configure options classes.

If a configuration class implements both IConfigureOptions and IConfigureNamedOptions interfaces, the IConfigureNamedOptions interface will take precedence, and the Configure method of the IConfigureOptions interface will not be executed.

You can configure the default instance using the Configure method of the IConfigureNamedOptions interface; the name of the options will be empty (equal to the member Options.DefaultName).

We can also leverage the following methods that extend the IServiceCollection interface:

MethodDescription
Configure<TOptions>Configure the default and named TOptions type inline or from a configuration section.
ConfigureAll<TOptions>Configure all options of type TOptions inline.
PostConfigure<TOptions>Configure the default and named TOptions type inline during the post-configuration phase.
PostConfigureAll<TOptions>Configure all options of type TOptions inline during the post-configuration phase.

 Table 9.3: configuration methods.

As we are about to see, the registration order is very important. The configurators are executed in order of registration. Each phase is independent of the other; thus, the sequence in which we arrange the configuration and post-configuration phases doesn’t influence one another.First, we must lay out the groundwork for our little program.

Creating the program

After creating an empty web application, the first building block is to create the options class that we want to configure:

namespace OptionsConfiguration;
public class ConfigureMeOptions
{
    public string?
Title { get; set; }
    public IEnumerable<string> Lines { get; set; } = Enumerable.Empty<string>();
}

We use the Lines property as a trace bucket. We add lines to it to visually confirm the order that the configurators are executed.Next, we define application settings in the appsettings.json file:

{
  “configureMe”: {
    “title”: “Configure Me!”,
    “lines”: [
      “appsettings.json”
    ]
  }
}

We use the configuration as a starting point. It defines the value of the Title property and adds a first line to the Lines property, allowing us to trace the order it is executed.Next, we need an endpoint to access the settings, serialize the result to a JSON string, and then write it to the response stream:

app.MapGet(
    “/configure-me”,
    (IOptionsMonitor<ConfigureMeOptions> options) => new {
        DefaultInstance = options.CurrentValue,
        NamedInstance = options.Get(NamedInstance)
    }
);

By calling this endpoint, we can consult the values of the default and named instances we are about to create.

ASP.NET Core configures the options when they are requested for the first time. In this case, both instances of the ConfigureMeOptions class are configured when calling the /configure-me endpoint for the first time.

If we run the program now, we end up with two empty instances, so before doing that, we need to tell ASP.NET about the configureMe configuration section we added to the appsettings.json file.

Leave a Reply

Your email address will not be published. Required fields are marked *



         


          Terms of Use | Accessibility Privacy