Nava.Settings
0.2.0
dotnet add package Nava.Settings --version 0.2.0
NuGet\Install-Package Nava.Settings -Version 0.2.0
<PackageReference Include="Nava.Settings" Version="0.2.0" />
<PackageVersion Include="Nava.Settings" Version="0.2.0" />
<PackageReference Include="Nava.Settings" />
paket add Nava.Settings --version 0.2.0
#r "nuget: Nava.Settings, 0.2.0"
#:package Nava.Settings@0.2.0
#addin nuget:?package=Nava.Settings&version=0.2.0
#tool nuget:?package=Nava.Settings&version=0.2.0
Nava.Settings
Lightweight strongly typed settings library for .NET applications with SQLite persistence, runtime updates, and scope-aware storage.
Features
- Strongly typed settings
- SQLite persistence
- In-memory caching for runtime settings
- Runtime updates with change notifications
- Scope-aware settings for users, tenants, workspaces, and other contexts
- Early startup settings loading
- Simple dependency injection integration
Installation
Nava.Settings requires .NET 10.
Install the package from NuGet:
dotnet add package Nava.Settings --version 0.2.0
Quick start
The following example configures SQLite storage, registers runtime settings, applies database migrations, and exposes endpoints for reading and updating the settings:
using Nava.Settings;
using Nava.Settings.Abstractions;
using Nava.Settings.DependencyInjection;
using Nava.Settings.Extensions;
var builder = WebApplication.CreateBuilder(args);
const string settingsDbPath = "settings.db";
builder.Services.AddSettingsWithSqlite(
_ => $"Data Source={settingsDbPath}");
builder.Services.AddRuntimeSettings<DemoSettings>();
var app = builder.Build();
await app.Services.InitializeApplicationSettingsAsync();
app.MapGet(
"/settings",
(ISettingsProvider<DemoSettings> provider) => provider.Settings);
app.MapPut(
"/settings",
async (
DemoSettings settings,
ISettingsProvider<DemoSettings> provider) =>
{
await provider.UpdateAsync(settings);
return Results.NoContent();
});
app.Run();
[SettingsKey("demo")]
public sealed class DemoSettings
{
public string Message { get; set; } = "Hello";
}
InitializeApplicationSettingsAsync() applies pending database migrations
and loads all registered runtime settings from SQLite.
Configuration
Register the SQLite settings storage:
builder.Services.AddSettingsWithSqlite(_ => "Data Source=settings.db");
Every settings type must have a unique SettingsKey:
[SettingsKey("demo")]
public sealed class DemoSettings
{
public string Message { get; set; } = "Hello";
}
Runtime settings
Runtime settings represent one application-wide instance of a settings type.
They are loaded during application startup, cached in memory, persisted to SQLite, and can notify subscribers when their value changes.
Register runtime settings
builder.Services.AddRuntimeSettings<DemoSettings>();
Initialize runtime settings
After building the application, initialize all registered runtime settings:
await app.Services.InitializeApplicationSettingsAsync();
This method also applies pending settings database migrations.
Read settings
Inject ISettingsProvider<T>:
public sealed class MyService(
ISettingsProvider<DemoSettings> settingsProvider)
{
public void DoWork()
{
var message = settingsProvider.Settings.Message;
Console.WriteLine(message);
}
}
Update settings
await settingsProvider.UpdateAsync(
new DemoSettings
{
Message = "Updated message"
});
The new value is persisted to SQLite and propagated to subscribers.
Subscribe to changes
settingsProvider.Subscribe(settings =>
{
Console.WriteLine($"Updated: {settings.Message}");
});
Scoped settings
Scoped settings allow storing multiple instances of the same settings type, identified by a scope ID.
A scope can represent:
- a user
- a tenant
- a workspace
- an organization
- any other application-defined context
Scoped settings are loaded on demand and are not cached globally.
Define scoped settings
[SettingsKey("user-appearance")]
public sealed class UserAppearanceSettings
{
public string Theme { get; set; } = "System";
public string Culture { get; set; } = "en";
}
Register scoped settings
builder.Services.AddScopedSettings<UserAppearanceSettings>();
Scoped providers are loaded on demand and do not have their own initialization
step. The application should still call
InitializeApplicationSettingsAsync() once at startup to apply database
migrations.
Read scoped settings
Inject IScopedSettingsProvider<T> and provide the scope ID:
public sealed class UserAppearanceService(
IScopedSettingsProvider<UserAppearanceSettings> settingsProvider)
{
public async Task<UserAppearanceSettings> GetAsync(
string userId)
{
return await settingsProvider.GetAsync(userId)
?? new UserAppearanceSettings();
}
}
Save scoped settings
await settingsProvider.UpdateAsync(
new UserAppearanceSettings
{
Theme = "Dark",
Culture = "de"
},
userId);
Remove scoped settings
await settingsProvider.RemoveAsync(userId);
After removal, subsequent reads return null. The application can then provide its own default settings.
Bootstrap settings
Some settings may be required before dependency injection or application services are fully initialized.
BootstrapReader<T> reads persisted settings directly from SQLite during early application startup.
const string settingsDbPath = "settings.db";
var settings =
new BootstrapReader<DemoSettings>(settingsDbPath)
.Read(
"demo",
() => new DemoSettings
{
Message = "Default message"
});
Console.WriteLine(settings.Message);
Typical use cases include:
- early infrastructure configuration
- logging initialization
- application mode selection
- settings required before the application host starts
Storage model
Settings are serialized as JSON and stored by a generated key.
Runtime settings use the settings type key:
demo
Scoped settings combine the settings type key with the supplied scope ID:
user-appearance:<scope-id>
Each settings type must use a unique [SettingsKey] value.
Notes
- SQLite storage is managed through Entity Framework Core.
- Runtime settings are cached in memory.
- Scoped settings are resolved for each requested scope.
- Runtime updates are persisted before change notifications are raised.
- Missing scoped settings return
null. - Runtime settings use their configured default values when no persisted value exists.
- Invalid persisted JSON read through runtime or scoped providers is logged and treated as a missing value.
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.EntityFrameworkCore.Sqlite (>= 10.0.10)
- SQLitePCLRaw.bundle_e_sqlite3 (>= 3.0.5)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.2.0 | 314 | 7/28/2026 |