Configuration for Windows and Uno Platform Applications

Following on from Dependency Injection and Logging, in this post we’re going to configure the IHostBuilder to load and access configuration information within a Windows or Uno Platform application.

We’ll pick up where we left off with the IHostBuilder setup to switch environments and configure logging.

var builder = this.CreateBuilder(args)
    .Configure(host => host
#if DEBUG
    // Switch to Development environment when running in DEBUG
    .UseEnvironment(Environments.Development)
#endif
    .UseLogging(configure: (context, logBuilder) =>
        {
            // Configure log levels for different categories of logging
            logBuilder
                .SetMinimumLevel(
                    context.HostingEnvironment.IsDevelopment() ?
                        LogLevel.Warning :
                        LogLevel.Error)

                // Default filters for core Uno Platform namespaces
                .CoreLogLevel(LogLevel.Trace);
        }, enableUnoLogging: true)
    );

Enable Configuration

The following code adds configuration support to the application.

.UseConfiguration()

Configuration information can be accessed by retrieving the IConfiguration instance.

var config = Host.Services.GetRequiredService<IConfiguration>();

By default any environment variables are added to the configuration information, which can be seen by inspecting the IConfiguration instance.

Configuration Sources

Additional configuration data can be loaded by specifying new sources. For example, the following code adds the data from “appsettings.json” that’s packaged as an embedded resource.

.UseConfiguration(
    configure: configBuilder =>
        configBuilder.EmbeddedSource<App>())

The EmbeddedSource extensions method also takes a parameter, includeEnvironmentSettings, which is true by default, that determines whether the application loads an environment specific version of the appsettings file. For example, if the environment is set to development (using the UseEnvironment method), the application will first load configuration data from “appsettings.json” and then load from “appsettings.development.json”, which will override any existing data with the same section name. This is useful for when you have different settings (such as web api endpoint) when debugging versus running in production.

Configuration Sections

Whilst it’s possible to access configuration values directly on the IConfiguration instance, another alternative is to register a type for a section of configuration to be deserialized to. For example, the following code registers the AppConfig type.

.UseConfiguration(
    configure: configBuilder =>
        configBuilder
            .EmbeddedSource<App>()
            .Section<AppConfig>())

By default this will register the AppConfig type for deserializing a section with the same name, for example the appsettings.json would contain a section AppSettings.

{
  "AppConfig": {
    "Environment": "Development"
 },
 ...
}

The AppSettings section will map to an entity such as the following – it can be a class or a record but does require a parameterless constructor:

public record AppConfig
{
    public string? Environment { get; init; }
}

You can register for a different section by providing the section name as a parameter to the Section extension method (eg Section<AppConfig>("appInfo")).

The registered section can be retrieved from the IServiceProvider by requesting an instance of IOptions<AppConfig>, such as the following code:

var appConfig = Host.Services.GetRequiredService<IOptions<AppConfig>>();
var appEnvironment = appConfig.Value.Environment;

In this post we’ve covered enabling configuration, adding sources and registering entities for accessing configuration section. There’s more information on Uno.Extensions configuration in the documentation

1 thought on “Configuration for Windows and Uno Platform Applications”

Leave a comment