chore: update sample app to show options pattern usage and verify reload of config works

This commit is contained in:
Stevan Freeborn
2026-04-02 19:56:35 -05:00
parent d0cf2224a5
commit d9affe2f75
3 changed files with 52 additions and 19 deletions
@@ -0,0 +1,8 @@
using System.Text.Json.Serialization;
namespace StevanFreeborn.Extensions.Configuration.Secure.Sample;
[JsonSerializable(typeof(ApiOptions))]
internal partial class AppJsonContext : JsonSerializerContext
{
}
@@ -1,37 +1,62 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using StevanFreeborn.Extensions.Configuration.Secure;
using StevanFreeborn.Extensions.Configuration.Secure.Configuration;
using StevanFreeborn.Extensions.Configuration.Secure.Sample; using StevanFreeborn.Extensions.Configuration.Secure.Sample;
using StevanFreeborn.Extensions.Configuration.Secure.Storage; using StevanFreeborn.Extensions.Configuration.Secure.Storage;
var builder = Host.CreateApplicationBuilder(); Action<ISecureConfigBuilder> configure = builder =>
const string configFileName = "appsettings.json";
var opts = new JsonStorageOptions()
{ {
FileName = configFileName, builder
.WithMachineIdKey()
.WithAesCryptoProvider()
.UseJsonFileStorage(new JsonStorageOptions())
.AddJsonAotContext(AppJsonContext.Default);
}; };
var storageProvider = new JsonFileStorageProvider(opts); var builder = Host.CreateDefaultBuilder()
.ConfigureAppConfiguration((_, b) =>
builder.Configuration.AddSecureConfig(storageProvider); {
b.AddSecureConfig(configure);
builder.Services.Configure<ApiOptions>( })
builder.Configuration.GetSection(nameof(ApiOptions)) .ConfigureServices((ctx, s) =>
); {
s.Configure<ApiOptions>(ctx.Configuration.GetSection(nameof(ApiOptions)));
builder.Services.AddSecureConfig() s.AddSecureConfig(configure);
.UseJsonFileStorage(opt => opt.FileName = configFileName); });
var app = builder.Build(); var app = builder.Build();
var options = app.Services.GetRequiredService<IOptions<ApiOptions>>(); var options = app.Services.GetRequiredService<IOptions<ApiOptions>>();
var optionsMonitor = app.Services.GetRequiredService<IOptionsMonitor<ApiOptions>>();
var secureConfig = app.Services.GetRequiredService<ISecureConfig>(); var secureConfig = app.Services.GetRequiredService<ISecureConfig>();
var scopeFactory = app.Services.GetRequiredService<IServiceScopeFactory>();
Console.WriteLine(options.Value); var firstScope = scopeFactory.CreateScope();
var firstSnapshot = firstScope.ServiceProvider.GetRequiredService<IOptionsSnapshot<ApiOptions>>();
var originalValue = await secureConfig.GetAsync<ApiOptions>(nameof(ApiOptions));
Console.WriteLine($"Config: {originalValue}");
Console.WriteLine($"IOptions: {options.Value}");
Console.WriteLine($"IOptionsSnapshot 1: {firstSnapshot.Value}");
Console.WriteLine($"IOptionsMonitor: {optionsMonitor.CurrentValue}");
await secureConfig.SetAsync( await secureConfig.SetAsync(
nameof(ApiOptions), nameof(ApiOptions),
new ApiOptions { ApiKey = "apiKey" } new ApiOptions { ApiKey = Guid.NewGuid().ToString() }
); );
var config = (IConfigurationRoot)app.Services.GetRequiredService<IConfiguration>();
config.Reload();
var updatedValue = await secureConfig.GetAsync<ApiOptions>(nameof(ApiOptions));
var secondScope = scopeFactory.CreateScope();
var secondSnapshot = secondScope.ServiceProvider.GetRequiredService<IOptionsSnapshot<ApiOptions>>();
Console.WriteLine($"Config: {updatedValue}");
Console.WriteLine($"IOptions: {options.Value}");
Console.WriteLine($"IOptionsSnapshot 2: {secondSnapshot.Value}");
Console.WriteLine($"IOptionsMonitor: {optionsMonitor.CurrentValue}");
@@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net11.0</TargetFramework> <TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>