EasyPrefs 1.3.4

dotnet add package EasyPrefs --version 1.3.4
                    
NuGet\Install-Package EasyPrefs -Version 1.3.4
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="EasyPrefs" Version="1.3.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="EasyPrefs" Version="1.3.4" />
                    
Directory.Packages.props
<PackageReference Include="EasyPrefs" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add EasyPrefs --version 1.3.4
                    
#r "nuget: EasyPrefs, 1.3.4"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package EasyPrefs@1.3.4
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=EasyPrefs&version=1.3.4
                    
Install as a Cake Addin
#tool nuget:?package=EasyPrefs&version=1.3.4
                    
Install as a Cake Tool

EasyPrefs

CI - Build, Test, Validate Pack CI Develop - Build, Test, Validate Pack Release - Publish NuGet Packages

EasyPrefs is a small, easy-to-use preferences library for .NET. It provides a simple, typed API for reading and writing user/application preferences, a cache with pending-change tracking, and a pluggable storage model so you can bring your own persistence.

  • Target framework: .NET 9.0

Packages

  • Core: EasyPrefs
  • JSON data provider: EasyPrefs.JSON

Install with the .NET CLI:

dotnet add package EasyPrefs
dotnet add package EasyPrefs.JSON

Core features

  • Typed reads/writes via SetPreference<T>(key, value) and GetPreference<T>(key).
  • Mandatory schemas per preference (type, default value and optional metadata).
  • Pluggable storage options via IPreferenceDataProvider and IPreferencesSchemaProvider.
  • In-memory caching for fast reads.
  • Pending change tracking.
  • Batch-saving via ApplyChanges().
    • Optional auto-apply on setting preferences.
  • Events for preference changes and pending-change updates.

Quick start

Below is a minimal example showing how to store preferences in a JSON file and read them back.

using EasyPrefs;
using EasyPrefs.Abstractions;
using EasyPrefs.JSON;
using Newtonsoft.Json;

// 1) Create a data provider (in this case using the provided EasyPrefs.JSON provider).
var dataProvider = new JsonPreferenceDataProvider(@"settings\preferences.json");

// Optional: customise JSON serialization.
provider.JsonSettings = new JsonSerializerSettings
{
    Formatting = Formatting.Indented
};

// 2) Create a schema provider with keys and default values.
var schemaProvider = new BuildablePreferenceSchemaProvider();
schemaProvider.AddSchema(new PreferenceSchema("ui.theme", typeof(string), "light"));
schemaProvider.AddSchema(new PreferenceSchema("ui.zoom", typeof(double), 1));

// 3) Create the main Preferences instance.
var preferences = new Preferences(dataProvider, schemaProvider);

// Optional: listen for change notifications
preferences.PreferencesChanged += (_, args) =>
{
    if(args.ChangedPreferenceKeys.Contains("ui.theme"))
    {
        // ...
    }
};

// 4) Write some preferences.
preferences.SetPreference("ui.theme", "dark");
preferences.SetPreference("ui.zoom", 1.25);

// Apply changes to the data provider - in this case save the changes in the JSON file.
preferences.ApplyChanges();

// 5) Read them later.
var theme = preferences.GetPreference<string>("ui.theme"); // "dark"
var zoom  = preferences.GetPreference<double>("ui.zoom"); // 1.25

Reading and writing values

You can read preferences by calling preferences.GetPreference<T>(string key) and write preferences by calling preferences.SetPreference<T>(string key, T? value). Setting a preference via SetPreference will store the new value in a list of pending changes. To apply the pending changes, you need to call preferences.ApplyChanges(). You may set preferences.AutoApplyChanges to true to automatically call ApplyChanges after every SetPreference call.

If you want to use interfaces (e.g. for IoC) Preferences implements:

  • IPreferenceReader for read-only access.
  • IPreferences for both read and write access.

If you change a value via SetPreference<T>, GetPreference<T> will return the old value until the changes are applied via ApplyChanges.

Caching and pending changes

  • All preferences are stored in a cache within the Preferences object.
  • Pending changes are stored in a list until ApplyChanges() is called (unless AutoApplyChanges is enabled).
  • Tracking:
    • HasPendingChanges() tells you if there are unapplied changes.
    • GetKeysWithPendingChanges() returns the keys that have pending changes.
    • ClearPendingChanges() discards unapplied changes (reverts the pending set, keeps the last persisted values).

Schemas

Each preference must have a schema that describes:

  • Key: Its unique identifier that is identical to the key used in GetPreference<T> and SetPreference<T>.
  • DataType: The expected data type for the value.
  • DefaultValue: Used when no explicit value is present or when the value was invalid during initialisation.
  • Optional metadata via a MetadataCollection.

Each preference must have an associated schema. Trying to access a preference without a schema will result in an error.

Metadata

You can store optional metadata in each PreferenceSchema via the Metadata property. Metadata is set and accessed much like preferences, with Add, GetValue<T>, TryGetValue<T> and HasMetadata functions.

You may use this to, for example, add preference names, descriptions and categories if you want to automatically populate your preference controls.

Data providers

EasyPrefs decouples the cached preferences from the persistence layer via IPreferenceDataProvider. This lets you plug in different backends (JSON files, databases, cloud KV stores, etc.).

Built-in JSON provider

EasyPrefs.JSON offers a JSON file-based provider:

  • Customize serialization via JsonPreferenceDataProvider.JsonSettings (uses Newtonsoft.Json).
  • Writes are designed to be resilient (i.e. temp file and backup) to minimise the risk of corruption.

Example:

using EasyPrefs.JSON;
using Newtonsoft.Json;

var provider = new JsonPreferenceDataProvider(@"<path>\prefs.json", allowMissingFile: true)
{
    JsonSettings = new JsonSerializerSettings
    {
        Formatting = Formatting.Indented
    }
};

Bring your own provider

Implement IPreferenceDataProvider. Your implementations should:

  • Initialise(): Prepare your storage and load any existing data, if necessary.
  • GetAllPreferences(): Return all persisting key/value pairs as they currently exist.
  • SetPreferences(changes): Save the provided changes to the persistent data layer.

Do not cache values in your custom IPreferenceDataProvider, as values are already cached within Preferences. Caching here would result in a doubled cache.

using System.Collections.Generic;
using EasyPrefs.Abstractions;

public sealed class MyPreferenceDataProvider : IPreferenceDataProvider
{
    public void Initialise()
    {
        // Connect to your store / ensure tables / read initial state, etc..
    }

    public IEnumerable<PreferenceValue> GetAllPreferences()
    {
        // Load and return all key/value pairs from your store.
    }

    public void ApplyChanges(IReadOnlyCollection<PreferenceValue> changes)
    {
        // Persist all changes.
        // Consider atomicity and crash-safety where possible.
    }
}

Thread Safety

  • The Preferences class should be thread-safe. Disclaimer: I have never worked on thread-safety before.

FAQ & Troubleshooting

Why are there no methods to see if a preference or schema exists?

The design philosophy behind this library is that there is little to no end-user interaction. You - the developer - should know exactly which preference keys are available and which are not.

I have changed a preference via SetPreference(...) but GetPreference(...) returns the old value.

Call ApplyChanges() after setting your preferences or enable Preferences.AutoApplyChanges.

License

See the LICENSE.md file in the repository.

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net9.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on EasyPrefs:

Package Downloads
EasyPrefs.JSON

EasyPrefs.JSON is an EasyPrefs extension that offers a JsonPreferenceDataProvider to save preferences in a JSON file.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.3.4 131 12/13/2025
1.3.3 120 12/13/2025
1.3.1 127 12/13/2025