-
Notifications
You must be signed in to change notification settings - Fork 49
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8164adc
commit 702da39
Showing
1 changed file
with
129 additions
and
4 deletions.
There are no files selected for viewing
133 changes: 129 additions & 4 deletions
133
doc/Learn/Tutorials/Configuration/HowTo-WritableConfiguration.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,137 @@ | ||
--- | ||
uid: Learn.Tutorials.Configuration.HowToWritableConfiguration | ||
--- | ||
|
||
# How-To: Writable Configuration | ||
|
||
This how-to is currently under construction. It will be available soon. | ||
**Writable Configuration** extends the standard, [read-only](xref:Learn.Tutorials.Configuration.HowToConfiguration) pattern by allowing for programmatic writing of configuration values at runtime. This is useful for scenarios where you want to persist user preferences or other trivial information that may be changed over time. `Uno.Extensions.Configuration` extends the `IOptionsSnapshot<T>` interface from [Microsoft.Extensions.Options](https://docs.microsoft.com/dotnet/api/microsoft.extensions.options) to support this. | ||
|
||
A special interface called `IWritableOptions<T>` is registered as a service when you use the `UseConfiguration()` extension method. In this tutorial, we will walk through how to use the `UpdateAsync()` method on this interface to modify values of a specific configuration section. For a refresher on configuration sections, see [Sections](xref:Overview.Configuration#sections). | ||
|
||
> [!NOTE] | ||
> It is common to see this referred to as the _settings_ pattern in certain documentation. This is because the `IOptions<T>` interface is often used to represent settings that can be changed by the user. | ||
## Step-by-steps | ||
|
||
### 1. Prepare for writing configuration values | ||
|
||
* Ensure your project has `Uno.Extensions.Configuration` installed as a NuGet [package](https://www.nuget.org/packages/Uno.Extensions.Configuration/). | ||
|
||
* To enable configuration, you first need to call `UseConfiguration()` on the `IHostBuilder` instance: | ||
|
||
```csharp | ||
private IHost Host { get; } | ||
|
||
protected override void OnLaunched(LaunchActivatedEventArgs e) | ||
{ | ||
var appBuilder = this.CreateBuilder(args) | ||
.Configure(host => { | ||
host | ||
.UseConfiguration() | ||
}); | ||
|
||
Host = appBuilder.Build(); | ||
... | ||
``` | ||
|
||
* Use the `EmbeddedSource<T>()` extension method to load configuration information from a JSON file called `appsettings.json` embedded inside the `App` assembly: | ||
|
||
```csharp | ||
private IHost Host { get; } | ||
|
||
protected override void OnLaunched(LaunchActivatedEventArgs e) | ||
{ | ||
var appBuilder = this.CreateBuilder(args) | ||
.Configure(host => { | ||
host | ||
.UseConfiguration(configure: configBuilder => | ||
configBuilder | ||
.EmbeddedSource<App>() | ||
); | ||
}); | ||
|
||
Host = appBuilder.Build(); | ||
... | ||
``` | ||
|
||
### 2. Define a configuration section | ||
|
||
* To model the configuration section you want to write to, author a new class or record with related properties: | ||
|
||
```csharp | ||
public partial record ToDoApp | ||
{ | ||
public bool? IsDark { get; init; } | ||
public string? LastTaskList { get; init; } | ||
} | ||
``` | ||
|
||
* For instance, the `IsDark` property could be used to toggle between light and dark themes, while `LastTaskList` could be used to persist the last task list the user was viewing. | ||
|
||
* Register the newly-defined configuration section by calling `Section<T>()` on `IConfigBuilder`: | ||
|
||
```csharp | ||
private IHost Host { get; } | ||
|
||
protected override void OnLaunched(LaunchActivatedEventArgs e) | ||
{ | ||
var appBuilder = this.CreateBuilder(args) | ||
.Configure(host => { | ||
host | ||
.UseConfiguration(configure: configBuilder => | ||
configBuilder | ||
.EmbeddedSource<App>() | ||
.Section<ToDoApp>() | ||
); | ||
}); | ||
|
||
Host = appBuilder.Build(); | ||
... | ||
``` | ||
|
||
### 3. Write configuration values | ||
|
||
* From any view model registered with the dependency injection (DI) container, you can now inject an instance of `IWritableOptions<T>` to write configuration values: | ||
|
||
```csharp | ||
public class SettingsViewModel | ||
{ | ||
private readonly IWritableOptions<ToDoApp> _appSettings; | ||
|
||
public SettingsViewModel(IWritableOptions<ToDoApp> appSettings) | ||
{ | ||
_appSettings = appSettings; | ||
} | ||
... | ||
``` | ||
|
||
* To update the `IsDark` property, create a method that calls `UpdateAsync()` on the injected instance: | ||
|
||
```csharp | ||
public class SettingsViewModel | ||
{ | ||
private readonly IWritableOptions<ToDoApp> _appSettings; | ||
|
||
public SettingsViewModel(IWritableOptions<ToDoApp> appSettings) | ||
{ | ||
_appSettings = appSettings; | ||
} | ||
|
||
public async Task ToggleTheme() | ||
{ | ||
await _appSettings.UpdateAsync(settings => settings with { | ||
IsDark = !settings.IsDark | ||
}); | ||
} | ||
... | ||
``` | ||
|
||
* Note that the `with` expression is used to create a new instance of the `ToDoApp` class with the updated value. This is because the `UpdateAsync()` method expects a function that returns a new instance of the class. | ||
|
||
## Work in progress 🚧 | ||
* The configuration section that was registered is not required to exist in any source beforehand. Sections like these will be created automatically when you call `UpdateAsync()`. | ||
|
||
### Have questions or feedback? | ||
## See also | ||
|
||
* Help us shape the documentation for this topic by providing feedback on the Uno.Extensions [repo](https://github.com/unoplatform/uno.extensions/discussions/categories/general) | ||
* [Configuration](xref:Overview.Configuration) | ||
* [Microsoft.Extensions.Configuration](https://docs.microsoft.com/dotnet/api/microsoft.extensions.configuration) | ||
* [`IOptionsSnapshot<T>`](https://docs.microsoft.com/dotnet/api/microsoft.extensions.options.ioptionssnapshot-1) |