dFakto.AppDataPath 3.0.0

dotnet add package dFakto.AppDataPath --version 3.0.0
                    
NuGet\Install-Package dFakto.AppDataPath -Version 3.0.0
                    
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="dFakto.AppDataPath" Version="3.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="dFakto.AppDataPath" Version="3.0.0" />
                    
Directory.Packages.props
<PackageReference Include="dFakto.AppDataPath" />
                    
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 dFakto.AppDataPath --version 3.0.0
                    
#r "nuget: dFakto.AppDataPath, 3.0.0"
                    
#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 dFakto.AppDataPath@3.0.0
                    
#: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=dFakto.AppDataPath&version=3.0.0
                    
Install as a Cake Addin
#tool nuget:?package=dFakto.AppDataPath&version=3.0.0
                    
Install as a Cake Tool

AppDataPath

Handle application data for dFakto.

AppDataPath gives an application a single, well-known root folder for its data, split into three standard subfolders, plus a lightweight versioned-migration system for upgrading the contents of that folder between application releases.

Directory layout

Given a base path, AppDataPath exposes three standard subdirectories:

Directory Purpose
config/ JSON files typically loaded as part of the host's configuration.
data/ Persistent application data. This is the directory affected by migrations.
temp/ Temporary files. Purged automatically at application startup.

If no base path is configured, it defaults to:

<SpecialFolder.ApplicationData>/<entry assembly name>

e.g. %AppData%\MyApp on Windows or ~/.config/MyApp on Linux.

Note: the configured base path must be an absolute/rooted path. Relative paths are not supported.

Installation

dotnet add package dFakto.AppDataPath

Quick start with IHostBuilder

AddAppData on IHostBuilder:

  1. Binds an AppDataConfig from the given configuration section (before any other configuration sources are added, so it can be set via environment variables, command line, etc.).
  2. Loads every *.json file found in the config/ directory (in alphabetical order) as an additional configuration source.
  3. Registers IAppData, IAppDataMigrator, IAppDataMigrationProvider and the bound AppDataConfig into the service collection.
using dFakto.AppDataPath;
using Microsoft.Extensions.Hosting;

Host.CreateDefaultBuilder(args)
    .AddAppData("AppDataPath") // name of the configuration section to bind AppDataConfig from
    .ConfigureServices((_, services) =>
    {
        services.AddTransient<IAppDataMigration, MyFirstMigration>();
        services.AddHostedService<MyHostedService>();
    })
    .Build()
    .Run();

Configuration section example (appsettings.json):

{
  "AppDataPath": {
    "BasePath": "/var/lib/myapp"
  }
}

BasePath is optional; omit it to use the default location described above.

Running migrations

Migrations are not run automatically — call IAppDataMigrator.Migrate() explicitly, typically at startup, before the rest of the application relies on data/:

public class MyHostedService : IHostedService
{
    public MyHostedService(IAppDataMigrator appDataMigrator)
    {
        appDataMigrator.Migrate();
    }

    // ...
}

Quick start without IHostBuilder

If you already have an IServiceCollection and want to configure AppDataPath manually:

using dFakto.AppDataPath;

var config = new AppDataConfig { BasePath = "/var/lib/myapp" };

services.AddAppData(config);

An optional minimal allowed version can be passed to either AddAppData overload (see Minimal allowed version below):

services.AddAppData(config, minimalAllowedVersion: new Version(2, 0));

Using IAppData

IAppData is registered as a singleton and gives access to the base path and its standard subdirectories, plus helpers for building paths and doing simple file I/O safely within them.

public class MyService
{
    private readonly IAppData _appData;

    public MyService(IAppData appData)
    {
        _appData = appData;
    }

    public void Example()
    {
        // Well-known roots
        var basePath = _appData.BasePath;
        var dataPath = _appData.DataPath;

        // Build a path inside a standard directory (does not create anything)
        var settingsPath = _appData.GetFilePath(AppDataDir.Config, "settings.json");

        // Build a path and ensure its parent directories exist
        var logPath = _appData.GetFilePathAndCreateParents(AppDataDir.Data, "logs", "app.log");

        // Read/write helpers, scoped to a standard directory
        _appData.WriteAllText("hello", AppDataDir.Data, "greeting.txt");
        var content = _appData.ReadAllText(AppDataDir.Data, "greeting.txt");

        // List files
        var files = _appData.GetDirectoryFiles("*.json", SearchOption.AllDirectories, AppDataDir.Config);

        // Delete
        _appData.DeleteFile(AppDataDir.Data, "greeting.txt");
        _appData.DeleteDirectory(excludeTopDir: true, force: true, AppDataDir.Temp);
    }
}

Every path-producing method rejects segments that would resolve outside of BasePath (e.g. via ..) by throwing an ArgumentException.

Writing migrations

A migration is a versioned unit of work applied to data/. Implement IAppDataMigration and register it in the service collection; migrations run in ascending order of Version, and only those with a Version greater than the current AppData version are applied:

using dFakto.AppDataPath;

public class AddDefaultSettingsMigration : IAppDataMigration
{
    public Version Version => new Version(1, 0);

    public void Upgrade(IAppData appData, IServiceProvider serviceProvider)
    {
        appData.WriteAllText("{}", AppDataDir.Data, "settings.json");
    }
}
services.AddTransient<IAppDataMigration, AddDefaultSettingsMigration>();

When IAppDataMigrator.Migrate() runs and one or more pending migrations are found:

  1. The current contents of data/ are backed up to a zip file.
  2. Each pending migration's Upgrade is invoked, in version order.
  3. If all migrations succeed, the AppData version is updated to the last applied migration's version, and the backup is discarded.
  4. If any migration throws, data/ is left as-is (partially migrated) and Migrate() rethrows as an InvalidOperationException. The backup is not restored during this call.

Recovery from a failed or interrupted migration always happens on the next call to Migrate(), not within the call that failed — this also covers the case where the process crashes outright mid-migration. On that next call, Migrate() detects the incomplete upgrade first and restores data/ from the backup (and rolls the AppData version back accordingly) before evaluating any pending migrations. In practice this means: if Migrate() throws, restart the application (or call Migrate() again) to complete the rollback before relying on the contents of data/.

Registering two migrations with the same Version is invalid and causes Migrate() to throw.

Minimal allowed version

Both AddAppData overloads accept an optional minimalAllowedVersion. If the current AppData version is older than minimalAllowedVersion (and this isn't a brand-new installation), Migrate() throws instead of attempting to migrate — use this to explicitly refuse to upgrade data that is too old for your migrations to handle correctly.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
3.0.0 201 8/3/2026
2.0.0 127 7/17/2026
1.3.0 284 6/11/2026
1.2.0 163 6/4/2026
1.1.1 835 12/7/2024
1.1.0 225 12/7/2024
1.0.0 12,250 5/19/2021
0.0.14 948 3/17/2021
0.0.13 613 1/8/2021
0.0.12 617 1/8/2021
0.0.11 697 11/14/2020
0.0.5 899 10/15/2020 0.0.5 is deprecated because it has critical bugs.
0.0.3 876 10/15/2020 0.0.3 is deprecated because it has critical bugs.
0.0.2 849 10/14/2020 0.0.2 is deprecated because it has critical bugs.
0.0.1 785 10/14/2020 0.0.1 is deprecated because it has critical bugs.