Persistent Properties
The most powerful feature of Stores. Mark a partial property with [Bind] and the DI source generator emits a getter/setter that reads from and writes to the backing key/value store — no INotifyPropertyChanged, no runtime reflection, no manual wiring. The class is automatically rehydrated on every read, so it survives app restarts.
-
Create a
partialclass withpartialproperties marked[Bind]:using Shiny;public partial class AppSettings{[Bind] // default storepublic partial string Theme { get; set; }[Bind]public partial bool NotificationsEnabled { get; set; }[Bind("secure")] // secure storepublic partial string Token { get; set; }[Bind(Key = "ui_density")] // override the storage key (defaults to property name)public partial int Density { get; set; }} -
Register it like any other service (the generator handles construction):
[Singleton]public partial class AppSettings { /* same as above */ }Or hand-write the registration if you prefer:
builder.Services.AddSingleton<AppSettings>(); -
Inject and use — every set persists, every get reads from the store:
public class SettingsViewModel(AppSettings settings){public void ToggleNotifications(){settings.NotificationsEnabled = !settings.NotificationsEnabled;}}
Direct Store Access
Section titled “Direct Store Access”If you don’t need binding, access the stores directly via the Shiny.Stores static accessor:
Shiny.Stores.Default.Set("theme", "dark");var theme = Shiny.Stores.Default.Get<string>("theme");
Shiny.Stores.Secure.Set("token", "abc123");
// Arbitrary keyed storesShiny.Stores.Keyed("my-store").Set("k", "v");The static accessor is self-bootstrapping on mobile/desktop — Default and Secure lazily construct the platform-native store on first access, so generated [Bind] property getters work as soon as the type is constructed. On Blazor WebAssembly (where the store needs IJSRuntime from the built provider) call host.Services.UseShinyStores() after host.Build() to snapshot the DI-resolved store into the static accessor.
For tests, use Shiny.Stores.Register(key, store) to swap in a MemoryKeyValueStore or any custom double, and Shiny.Stores.Reset() to clear state between runs.