dFakto.AppDataPath
3.0.0
dotnet add package dFakto.AppDataPath --version 3.0.0
NuGet\Install-Package dFakto.AppDataPath -Version 3.0.0
<PackageReference Include="dFakto.AppDataPath" Version="3.0.0" />
<PackageVersion Include="dFakto.AppDataPath" Version="3.0.0" />
<PackageReference Include="dFakto.AppDataPath" />
paket add dFakto.AppDataPath --version 3.0.0
#r "nuget: dFakto.AppDataPath, 3.0.0"
#:package dFakto.AppDataPath@3.0.0
#addin nuget:?package=dFakto.AppDataPath&version=3.0.0
#tool nuget:?package=dFakto.AppDataPath&version=3.0.0
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:
- Binds an
AppDataConfigfrom the given configuration section (before any other configuration sources are added, so it can be set via environment variables, command line, etc.). - Loads every
*.jsonfile found in theconfig/directory (in alphabetical order) as an additional configuration source. - Registers
IAppData,IAppDataMigrator,IAppDataMigrationProviderand the boundAppDataConfiginto 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:
- The current contents of
data/are backed up to a zip file. - Each pending migration's
Upgradeis invoked, in version order. - If all migrations succeed, the AppData version is updated to the last applied migration's version, and the backup is discarded.
- If any migration throws,
data/is left as-is (partially migrated) andMigrate()rethrows as anInvalidOperationException. 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 | Versions 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. |
-
.NETStandard 2.0
- Microsoft.Extensions.Hosting (>= 10.0.10)
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.3 | 876 | 10/15/2020 | |
| 0.0.2 | 849 | 10/14/2020 | |
| 0.0.1 | 785 | 10/14/2020 |