Configuration
Uno.Extensions.Configuration
provides a uniform way to read or write configuration data from a number of distinct sources. The implementation of IOptions<T>
from Microsoft.Extensions.Options allows for read-only access to values organized into configuration sections. The writable configuration pattern supports the ability to update configuration values at runtime.
This feature uses Microsoft.Extensions.Configuration for any configuration related work. For more documentation on configuration, read the references listed at the bottom.
Using Configuration
The IConfiguration
interface is registered as a service when the UseConfiguration()
extension method is used.
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
var appBuilder = this.CreateBuilder(e)
.Configure(
host => host
.UseConfiguration( /* ... */)
);
Host = appBuilder.Build();
...
}
IConfiguration
is then available to be accessed by any class instantiated by the dependency injection (DI) container:
public class MyService : IMyService
{
private readonly IConfiguration configuration;
public MyService(IConfiguration configuration)
{
this.configuration = configuration;
}
...
}
App settings file sources
To use appsettings.json
file packaged as EmbeddedResource in the application:
private IHost Host { get; }
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
var appBuilder = this.CreateBuilder(e)
.Configure(
host => host
.UseConfiguration(
builder => builder
.EmbeddedSource<App>()
)
);
Host = appBuilder.Build();
...
}
The recommended approach to specifying a configuration file source, especially when targeting Web Assembly (WASM), is to register it as an EmbeddedResource as described above. Configuration data read from embedded resources has the benefit of being available to the application immediately upon startup. However, it is still possible to package the file source as Content instead:
private IHost Host { get; }
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
// NOT RECOMMENDED FOR WEB ASSEMBLY
var appBuilder = this.CreateBuilder(e)
.Configure(
host => host
.UseConfiguration(
builder => builder
.ContentSource<App>()
)
);
Host = appBuilder.Build();
...
}
Both EmbeddedSource
and ContentSource
methods will also create settings files that are specific to the current environment by default, appsettings.<hostenvironment>.json
(eg appsettings.development.json
). This can be disabled by setting the includeEnvironmentSettings
argument to false
(default value is true
):
private IHost Host { get; }
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
var appBuilder = this.CreateBuilder(e)
.Configure(
host => host
.UseConfiguration(
builder => builder
.EmbeddedSource<App>(includeEnvironmentSettings: false)
)
);
Host = appBuilder.Build();
}
Tip
It is recommended to ensure all configuration information is read before creation of the IHost
instance by only using EmbeddedSource
. This will allow configuration to determine which services are created.
Sections
Map configuration section to class and register with dependency injection (DI):
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
var appBuilder = this.CreateBuilder(e)
.Configure(
host => host
.UseConfiguration(
builder => builder.EmbeddedSource<App>()
.Section<CustomIntroduction>()
)
);
...
}
This can be accessed from any class created by the DI container:
public class MainViewModel : ObservableObject
{
private readonly IOptions<CustomIntroduction> customConfig;
public MainViewModel(IOptions<CustomIntroduction> customConfig)
{
this.customConfig = customConfig;
}
}
Updating configuration values at runtime
The writable configuration feature enables the ability to update configuration values at runtime. This pattern may also be referred to as the settings pattern in certain documentation. With the UseConfiguration()
extension method, IWritableOptions<T>
is registered as a service. The recommended approach when specifying a set of settings for this feature is to use configuration sections.
Registering a configuration section for writable configuration does not require it to exist in any source. The section will be created if it does not exist.
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
var appBuilder = this.CreateBuilder(e)
.Configure(
host => host
.UseConfiguration(builder =>
builder
.EmbeddedSource<App>()
.Section<DiagnosticSettings>()
)
);
...
}
DiagnosticSettings
can be defined as a record:
public record DiagnosticSettings(bool HasBeenLaunched);
Modify a setting value by calling Update()
on the injected IWritableOptions
instance:
public MainViewModel(IWritableOptions<DiagnosticSettings> debug)
{
debug.Update(debugSetting =>
debugSetting with { HasBeenLaunched = true }
);
}